webpack5を使ってvue開発環境を構築する
序文
通常、vue プロジェクトを開発するときは、vue 公式 Web サイトの推奨に従って、次のコマンドを直接実行してプロジェクトを作成します。
npm init vue@latest
このコマンドは、Vue の公式プロジェクト スキャフォールディング ツールである create-vue をインストールして実行します。
ただし、これはこの記事の主題ではありません。この記事では、Webpack 5.0 を使用して Vue 開発環境を構成するプロセスを記録し、プロジェクトの作成プロセスで Vue CLI が行うことについて詳しく説明します。
準備
Webpackの概念の紹介
以前に webpack4 を使用して vue 開発環境を構成したことがある場合は、 webpack4 から webpack5 への移行を確認できます。
環境構成
プロジェクトを初期化する
新しいプロジェクトのルート ディレクトリ フォルダーを作成し、そのフォルダーにプロジェクト名として名前を付けます。フォルダーに入り、次のコマンドを実行します。
npm init -y
ファイルがルート ディレクトリに生成されpackage.json
、次のように変更されます。
{
"name": "webpack5-vue-template",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
},
"keywords": [],
"author": "ricky",
"license": "ISC"
}
Webpackをインストールする
注文の実行:
npm i webpack webpack-cli -D
package.json
に表示されます:
{
"name": "webpack5-vue-template",
...
"devDependencies": {
"webpack": "^5.86.0",
"webpack-cli": "^5.1.4"
}
}
パッケージング環境を構成する
プロジェクトのルート パスの下に新しいディレクトリを作成しbuild
、その中に 3 つの新しいファイルを作成しますjs
。
webpack.common.js
パブリック環境の構成webpack.dev.js
開発環境の構成webpack.prod.js
本番環境の構成
package.json の script パラメータを変更し、スクリプト実行時にスクリプト内で判断するための環境変数を渡します。
{
...
"scripts": {
"build:dev": "webpack --progress --config ./build/webpack.dev.js",
"build": "webpack --progress --node-env production --config ./build/webpack.prod.js"
},
...
}
ルート ディレクトリの下に、src
ビジネス コードを保存する新しいフォルダーを作成し、その中に新しいフォルダーを作成しますmain.js
。assets
assets
ディレクトリ内に新しいfonts
andディレクトリを作成しますimg
。
webpack-merge をインストールする
共通の構成を環境固有の構成とマージするには、この依存関係をインストールします。最後に、予想される構成ファイルをエクスポートします
npm i webpack-merge -D
webpack.common.js
const path = require('path');
module.exports = {
entry: {
main: path.resolve(__dirname, '../src/main.js')
},
output: {
path: path.resolve(__dirname, '../dist')
},
}
解決の構成: 頻繁に使用されるファイル パスの一部を省略します
...
module.exports = {
entry: {
...
},
resolve: {
alias: {
'@': path.resolve(__dirname, '../src'),
'@img': path.resolve(__dirname, '../src/assets/img')
},
extensions: ['.js', '.vue']
},
...
}
webpack.dev.js
const {
merge } = require('webpack-merge')
const commonConfig = require('./webpack.common')
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'
const devConfig = {
mode,
output: {
filename: 'js/[name].js',
chunkFilename: 'js/[name].chunk.js'
}
}
module.exports = merge(commonConfig, devConfig)
webpack.prod.js
const {
merge } = require('webpack-merge')
const commonConfig = require('./webpack.common')
const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'
const prodConfig = {
mode,
output: {
filename: 'js/[name].[contenthash:8].js',
chunkFilename: 'js/[name].[contenthash:8].chunk.js'
}
}
module.exports = merge(commonConfig, prodConfig)
distディレクトリにindex.htmlを生成します。
ルート ディレクトリに新しいものを作成します/public/index.html
。index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="app"></div>
</body>
</html>
プラグインの依存関係をインストールしますhtml-webpack-plugin
。
npm i html-webpack-plugin -D
HTML テンプレートを次のように設定しますwebpack.common.js
。
...
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html'),
title: 'This is a template'
})
],
output: {
...
}
}
開発環境を構成する
DevServer ホット アップデート
サーバーの依存関係をインストールし、次のコマンドを実行します。
npm i webpack-dev-server -D
次のプロパティwebpack.dev.js
を構成します。devServer
const path = require('path')
...
const devConfig = {
...
devServer: {
static: path.resolve(__dirname, '../dist'),
port: 3000,
open: true,
hot: true
},
output: {
...
}
}
...
属性の実行コマンドを次のようにpackage.json
設定しますscript
。
{
...
"scripts": {
"serve": "webpack-dev-server --progress --config ./build/webpack.dev.js",
...
},
...
}
バベル言語変換
開発依存関係をインストールします。
npm i babel-loader @babel/core @babel/preset-env -D
本番環境の依存関係をインストールします。
npm i @babel/polyfill core-js
パブリック設定でjs ファイルの読み込みルールwebpack.common.js
を設定します。module.roules
...
module.exports = {
...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
plugins: [
...
],
...
}
プロジェクトのルート ディレクトリに新しいファイルを作成しますbabel.config.js
。
module.exports = {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3
}
]
]
}
バベルを使用する前に
バベルで変身後
CSS とスタイラス スタイルのパッケージ化
scss 以下にすることもできます。この例ではスタイラスを使用します。最初に依存関係をインストールします。
npm i css-loader style-loader postcss-loader autoprefixer stylus stylus-loader -D
CSS スタイルの変換はパッケージ化時に変換されるため、インストールは開発に依存します。で設定しますwebpack.dev.js
:
...
const devConfig = {
...
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
'postcss-loader'
]
},
{
test: /\.styl(us)$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
//启用/禁用或者设置在 css-loader 前应用的 loader 数量
importLoaders: 2
}
},
'postcss-loader',
'stylus-loader'
]
}
]
},
output: {
...
}
}
...
ここで使用するのでpostcss
、ルート ディレクトリに新しい設定ファイルを作成しますpostcss.config.js
。
module.exports = {
plugins: [
require('autoprefixer') // 属性根据浏览器不同,自动添加样式前缀
]
}
ルート ディレクトリの下に新しいものを作成します.browserslistrc
。
> 1%
last 2 versions
not dead
not ie 11
最適化:本番環境では、別の CSS スタイル ファイルに抽出され、スタイル コードが圧縮されます。開発環境は必要ありません。
-
インストールの依存関係:
npm i mini-css-extract-plugin css-minimizer-webpack-plugin -D
webpackプラグインのリンク:
-
構成
webpack.prod.js
:... const MiniCssExtractPlugin = require('mini-css-extract-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') ... const prodConfig = { ... module: { rules: [ { test: /\.css$/, use: [ // 压缩css文件,需配置的loader MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 1 } }, 'postcss-loader' ] }, { test: /\.styl(us)$/, use: [ // 压缩css文件,需配置的loader MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 2 } }, 'postcss-loader', 'stylus-loader' ] } ] }, optimization: { minimizer: [ // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释 // `...`, new CssMinimizerPlugin(), // 这将仅在生产环境开启 CSS 优化。 // 如果还想在开发环境下启用 CSS 优化,请将 optimization.minimize 设置为 true: ] }, plugins: [ new MiniCssExtractPlugin({ // 决定输出的每个 CSS 文件的名称 filename: 'css/[name].[contenthash:8].css', // 决定非入口的 chunk 文件名称,仅在 webpack@5 下可用 chunkFilename: 'css/[name].[contenthash:8].chunk.css' }) ], output: { ... } } ...
フォント、画像、メディアなどの静的リソースのパッケージ化
構成webpack.common.js
:
...
const isProduction = process.env.NODE_ENV === 'production'
module.exports = {
...
module: {
rules: [
...
{
test: /\.(ttf|woff|woff2|eto|svg)$/,
exclude: path.resolve(__dirname, '../src/assets/img'),
type: 'asset',
parser: {
dataUrlCondition: {
//如果一个模块源码大小小于 maxSize,那么模块会被作为一个 Base64 编码的字符串注入到包中, 否则模块文件会被生成到输出的目标目录中。
maxSize: 4 * 1024 // 4kb
}
},
generator: {
filename: isProduction
? 'static/fonts/[name].[contenthash:8][ext]'
: 'static/fonts/[name][ext]'
}
},
{
test: /\.(jpe?g|png|gif|svg)$/,
exclude: path.resolve(__dirname, '../src/assets/fonts'),
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 4 * 1024
}
},
generator: {
filename: isProduction ?
'static/img/[name].[contenthash:8][ext]' :
'static/img/[name][ext]'
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
type: 'asset/resource',
generator: {
filename: isProduction ?
'static/video/[name].[contenthash:8][ext]' :
'static/video/[name][ext]'
}
}
]
},
...
}
rules.Rule.type、つまりリソースモジュールの説明については、公式サイトの説明を参照してください。
vue単体ファイルのパッケージ構成
インストールの依存関係:
- ビュー フレームワーク vue をインストールします。
npm i vue
- ローダー、コンパイラーをインストールします。
npm i vue-loader @vue/compiler-sfc -D
構成webpack.common.js
:
...
const {
VueLoaderPlugin } = require('vue-loader')
...
module.exports = {
...
module: {
rules: [
...
{
test: /\.vue$/,
loader: 'vue-loader'
},
...
]
},
plugins: [
...
new VueLoaderPlugin()
],
...
}
ここまででvueの開発環境が構築できました!
Vue エコシステム機能を統合する
アプリエントリー
src
ディレクトリ内に、新しい を作成しますApp.vue
。
<template>
<div class="app">{
{ msg }}</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
msg: 'Hello world'
}
}
}
</script>
<style lang="stylus" scoped>
.app
color: skyblue
</style>
src
ディレクトリ内に、新しい を作成しますmain.js
。
import {
createApp } from 'vue'
import App from './App'
const app = createApp(App)
app.mount('#app')
Vue ルーターと Vuex を追加する
本番環境の依存関係をインストールします。
npm i vue-router vuex
src
ディレクトリ配下にrouter
とstore
ディレクトリをそれぞれ作成し、順次新しいindex.js
ファイルを作成します 具体的な使用方法はvueの公式サイトを参照してください。
ファイルを編集します/router/index.js
:
import {
createRouter, createWebHistory } from 'vue-router'
import Home from '@/views/Home'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// 懒加载。webpackChunkName 指定chunkname为 about
component: () => import(/* webpackChunkName: "about" */ '@/views/About')
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
注:ここでは のルーティング モードが使用されているhistory
ため、webpack.dev.js
開発環境で設定する必要があります。
...
const devConfig = {
...
devServer: {
...
// 配置history路由模式
historyApiFallback: true
},
...
}
...
ファイルを編集します/store/index.js
:
import {
createStore } from 'vuex'
const store = createStore({
state: {
count: 1
},
actions: {
add ({
commit }) {
commit('add')
}
},
mutations: {
add (state) {
state.count++
}
},
getters: {
getCount (state) {
return state.count
}
}
})
export default store
ルーターとストアを main.js に追加します。
import {
createApp } from 'vue'
import App from './App'
import router from './router'
import store from './store'
const app = createApp(App)
app.use(router).use(store).mount('#app')
Vue3 でvuex を piniaハイパーリンクに置き換えます
環境変数を定義する
ツリーシェーキングを改善するには、vue3.x プロジェクトに 2 つの変数を設定する必要があります
改訂webpack.common.js
...
const webpack = require('webpack')
...
module.exports = {
...
plugins: [
...
new webpack.DefinePlugin({
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false
})
],
...
}
梱包仕様の設定
パッケージ化時に公開ファイルをコピーする
インストールの依存関係:
npm i copy-webpack-plugin -D
構成では、パッケージ化するときに次のファイルをwebpack.common.js
ディレクトリに直接コピーします。public
dist
...
const CopyPlugin = require('copy-webpack-plugin')
...
module.exports = {
...
plugins: [
...
new CopyPlugin({
patterns: [
{
from: path.resolve(__dirname, '../public'),
to: path.resolve(__dirname, '../dist'),
filter: (resourcePath) => {
if (resourcePath.includes('/public/index.html')) {
return false
}
return true
}
}
]
})
],
...
}
ESLint コードの仕様
インストールの依存関係:
npm i eslint eslint-webpack-plugin @babel/eslint-parser -D
npm i eslint-config-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-n -D
npm i eslint-plugin-vue -D
eslint を実行します。
npx eslint --init
コマンド実行後、プロンプトに従って設定項目を選択します。次に、構成ファイルがプロジェクトのルート ディレクトリに生成されるので.eslintrc.js
、ファイルを変更します。
module.exports = {
root: true,
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/vue3-essential',
'standard'
],
parserOptions: {
parser: '@babel/eslint-parser'
},
plugins: [
'vue'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'vue/multi-word-component-names': 0
}
}
ルートディレクトリに新しい.eslintconfig
ファイル.eslintignore
を作成します
-
.editorconfig
[*.{js,jsx,ts,tsx,vue}] indent_style = space indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true
-
.eslintignore
/build/ /dist/
Webpack で eslint プラグインを設定する
webpack.common.js 中:
...
const ESLintPlugin = require('eslint-webpack-plugin')
...
module.exports = {
...
plugins: [
...
new ESLintPlugin({
extensions: ['js', 'jsx', 'ts', 'tsx', 'vue']
})
],
...
}
パッケージ化する前に、最後にパッケージ化されたコンテンツをクリアします
構成webpack.common.js
:
...
module.exports = {
...
output: {
...
clean: true
}
}
ソースマップ
この構成は通常、開発環境でのみ必要となるため、webpack.dev.js
次のように構成しますdevtool
。
...
const devConfig = {
mode,
devtool: 'eval-cheap-module-source-map',
...
}
...
パッケージ分析
Webpack のパッケージ化結果の分析はインストールによって異なります。npm i webpack-bundle-analyzer -D
ディレクティブを次のように設定しますpackage.json
。
{
...
"scripts": {
...
"analyze": "webpack --progress --analyze --node-env production --config ./build/webpack.prod.js"
},
...
}
いくつかのヒントをオフにする
運用環境でパッケージ化する場合、大きなファイルに対してパフォーマンスに関するプロンプトが表示される場合がありますが、これは構成によってオフにすることができます。
変更webpack.prod.js
:
...
const prodConfig = {
...
performance: false,
output: {
...
}
}
...
他の構成
git が送信されるとき、一部のファイルはコミットされないように無視する必要があります。構成: 次のディレクトリに新しいファイルを作成します.gitignore
。
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
最後に書きます
上記の操作は webpack5 で Vue プロジェクト環境を構築するプロセス全体であり、実際の操作中に webpack の構成に再度慣れます。
この記事の参考文献: