首先是vue项目结构目录
在app.vue中引用组件helloworld.vue
初始化需要的模块
1.安装webpack webpack-cli
npm install --save-dev webpacak webpack-cli
或
yarn add webpack webapck-cli --dev
此时编译启动会报错 需安装其他模块,具体如下:
npm install vue vue-loader vue-template-compiler less less-loader css css-loader style-loader file-loader --save-dev
或
yarn add vue vue-loader vue-template-compiler less less-loader css css-loader style-loader file-loader --dev
2.在webpack.config.js中使用CommonJs规范配置入口及输出位置,即本文中的webpack.common.js:
const path = require("path")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const vueLoaderPlugin = require('vue-loader/lib/plugin-webpack5')
// 使用commonjs规范编写
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, './dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// enable CSS Modules
modules: false,
}
}
]
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'less-loader',
options: {
lessOptions: {
strictMath: true,
},
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
use: {
loader: 'url-loader',
options: {
outputPath: 'img',
name: '[name].[ext]'
}
}
},
{
test: /\.vue$/,
use: [
'vue-loader'
]
}
]
},
plugins: [
new HtmlWebpackPlugin(),
new vueLoaderPlugin()
]
}
3.其中遇到的问题:
- 3.1
package.json中配置
// package.json 中部分代码
"scripts": {
"serve": "webpack serve --config webpack.config.js"
}
目的是不用每次都使用yarn webpck --config webpack.config.js执行编译,因为这里设置了分环境使用不同的配置文件,所以每次打包运行都需要指定配置文件.
-
3.2 报错
Invalid configuration object. Webpack has been initialised using a configura原因:
package.json文件中配置的webpack版本与所使用版本不一致- 检查代码中是否存在
module写成了modules解决方法: - 重新安装webpack版本:
yarn add webpack --dev || npm install webpack --save-dev
-
3.3 报错
ERROR in Entry module not found: Error: Can't resolve 'babel-loader'原因:
- 这类错误未能找到这个模块,安装即可:
yarn add babel-loader --dev || npm install babel-loader --save-dev
- 这类错误未能找到这个模块,安装即可:
-
3.4 报错
You may need an additional loader to handle the result of these loaders.原因: 需要一个loaders来加载一些运行后的结果
解决方法: 安装对应模块:
vue-loader vue-template-compiler再次执行扔报错:
在
webpack.common.js中导入对应的plugin:
const vueLoaderPlugin = require('vue-loader/lib/plugin-webpack5')
.... // 省略代码
plugins: [
new HtmlWebpackPlugin(),
new vueLoaderPlugin()
]
4. webpack.prod.js中:
需求分析:
- 需要使用
common中的部分 - 需要单独压缩代码, 并且打包
public中的文件:new CopyWebpackPlugin(['public'])所以可以得到以下代码:
const common = require('./webpack.common')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = Object.assign({}, common, {
mode: "production",
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin(['public'])
]
})
此时,assign方法后面拼接的对象会把前面对象的覆盖掉,所以不适合,使用webpack-merge模块提供的方法去合并common中的配置.
安装及引入:
yarn add webpack-merge --dev
// 或
npm install webpack-merge --save-dev
// 引入
const commonConfig = require('./webpack.common')
const {merge} = require('webpack-merge')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = merge(commonConfig, {
mode: 'production',
devtool: 'nosources-source-map',
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
// enable CSS Modules
modules: false,
}
}
]
}
]
},
optimization: {
usedExports: true,// 标记未引用代码
minimize: true,//移除未使用代码
splitChunks: {
chunks: 'all'
}
},
plugins: [
new CleanWebpackPlugin(),
]
})
- 4.1 编译出现:
Multiple chunks emit assets to the same filename bundle.js报错- 原因: 在打包多文件入口时,只指定了一个输出文件名,应该每个需要打包的文件根据文件名打包输出
- 解决方案: 在
webpack.common.js中:
output: {
filename: './js/[name].js',
path: resolve(__dirname, 'build')
}
5.配置webpack.dev.js
需求分析:
- 需要使用
common中的部分 - 需要使用
eslint在开发阶段杜绝格式及语法错误 - 在
vue中集成eslint,需要通过loader加载,并在.eslintrc.js中plugin项配置 所以可以得到以下代码:
const commonConfig = require('./webpack.common')
const {merge} = require('webpack-merge')
const path = require('path')
module.exports = merge(commonConfig,{
mode:'development',
devtool:'eval-cheap-module-source-map',
module:{
rules:[
{
test: /\.js$/,
exclude: /node_modules/,
use: 'eslint-loader',
enforce:'pre'
},
]
},
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 9000,
// open: true,
hot: true
}
})
- 5.1 需安装
eslint eslint-loader:
npm install eslint eslint-loader --save-dev
// 或
yarn add eslint eslint-loader --dev
- 5.2 初始化
.eslintrc.js文件:
npx eslint --init
// 或
yarn eslint --init
- 5.3 得到
.eslintrc.js文件,并配置:
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'plugin:vue/essential',
'standard'
],
parserOptions: {
ecmaVersion: 12
},
plugins: [
'vue'
],
rules: {
}
}
6 在package.json中配置相关命令
"scripts": {
"build": "webpack --config webpack.prod.js",
"serve": "webpack serve --config webpack.dev.js",
"lint": "npm run serve"
},
一些列操作后,package.json如下:
{
"name": "vue-app-base",
"version": "0.1.0",
"private": true,
"scripts": {
"build": "webpack --config webpack.prod.js",
"serve": "webpack serve --config webpack.dev.js",
"lint": "npm run serve"
},
"dependencies": {
"@babel/core": "^7.12.16",
"@babel/preset-env": "^7.12.16",
"babel-loader": "^8.2.2",
"core-js": "^3.6.5",
"vue": "^2.6.12"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.11",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^7.0.0",
"css": "^3.0.0",
"css-loader": "^5.0.2",
"eslint": "^7.20.0",
"eslint-config-standard": "^16.0.2",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-vue": "^7.6.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.1.0",
"less": "^4.1.1",
"less-loader": "^8.0.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"vue-loader": "^15.9.6",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.12",
"webpack": "^5.23.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.9.0",
"webpack-merge": "^5.7.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}