本次项目属于练手项目,使用的是 vue-cli 新建的新手引导页面,项目本身没有特别复杂的逻辑,而且这里也不涉及到 Vue 的学习,只是会通过逐步分解完成使用 webpack 对项目完成最终的打包。
本次会使用到的 插件(plugins) 和 加载器(loaders) 有:
webpack & webpack-cli
vue-loader & vue-template-compiler
style-loader & less & less-loader
这个根据具体的项目需求可以修改,这里使用了 LESS,所以需要额外搭配 less & less-loader
只用 css 的可以只使用 style-loader
file-loader & url-loader
这里也存在二选一的关系,url-loader 起到的是优化的作用,它的 fallback 是 file-loader,所以使用 url-loader 必须安装 file-loader
反之只用 file-loader 可以不用安装 url-loader
htmlWebpackPlugin
解决了 HTML 文件,也就是入口文件的迁徙和模板问题
clean-webpack-plugin
自动清除之前编译好的文件
copy-webpack-plugin
满足了迁徙其他静态文件的需求
结构如下,需要编译的文件有 vue, less 和 JavaScript,需要压缩的文件有打包后的 JavaScript 和 HTML 文件。
注*:这个项目是一个使用 vue-cli 创建的初始项目,只不过移除了脚手架中自动打包的部分。
这一部分主要是实现一些基础功能,这个项目已经是一个初始化好了的 node 项目,否则需要使用 init
命令去进行初始化。
D:\\vue-app-base>npm i webpack webpack-cli -D
i
是 install 的缩写,-D
是 --save-dev
的缩写,这样就将 webpack 和 webpack-cli 以开发依赖安装好了。
查看 package.json
文件,就会发现 devDependiencies 已经更新:
{
"devDependencies": {
"webpack": "^5.41.0",
"webpack-cli": "^4.7.2"
}
}
这时候可以新添一条脚本命令让 npm 去运行 webpack:
{
"script": {
"build": "webpack"
}
}
这个时候尝试在命令行运行 npm run build
会得出大量的报错结果,但是这可以证明命令可以正常被运行。
D:\\vue-app-base>npm run build
> [email protected] build D:\\vue-app-base
> webpack
assets by status 0 bytes [cached] 1 asset
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value.
Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
ERROR in main
Module not found: Error: Can't resolve './src' in 'D:\\vue-app-base
# 省去大量报错信息
webpack 5.41.0 compiled with 1 error and 1 warning in 163 ms
最后在根目录下新建 webpack.config.js
作为 webpack 的入口,并且套入模板,对打包模式、入口和出口文件进行配置。
webpack 的配置文件可以导出一个对象,通过导出对象的属性就可以完成相应的配置选项。
// npm原有的模块
const path = require('path');
module.exports = {
// 入口文件
entry: './src/main.js',
// 导出的部分
output: {
// 导出的文件名
filename: 'bundle.js',
// 导出的文件名会放置的路径
path: path.resolve(__dirname, 'dist/'),
},
};
这个时候再去运行 npm run build
,会得出下面的结果:
D:\\vue-app-base>npm run build
> [email protected] build D:\\vue-app-base
> webpack
assets by status 4.16 KiB [cached] 1 asset
runtime modules 718 bytes 3 modules
cacheable modules 770 bytes
./src/main.js 169 bytes [built] [code generated]
./src/App.vue 537 bytes [built] [code generated] [1 error]
./src/style.less 64 bytes [built] [code generated] [1 error]
# 省略掉一堆报错信息
webpack 5.41.0 compiled with 4 errors and 1 warning in 216 ms
这次调出了 4 个 errors 和 1 个 warning,这是件好事儿,至少把所有的报错消息一个个的列了出来,这样也有可以开始 debug 的点了。最怕的不是报错信息多,而是报错信息没有头绪,不知道从哪开始。
webpack 给出了项目中的几个问题,分别是:
这个是说 mode 没有设置,会默认以生产环境进行开发
ERROR in ./src/App.vue 1:0
这个提示就很明显了,webpack 说:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
需要一个 Vue 的 loader 去解决问题
这个问题应该也是一样的,具体报错信息如下:
Module not found: Error: Can't resolve 'vue' in 'D:\\vue-app-base\src'
这个问题是属于 output 文件的问题了,先解决上面打包的问题,再看看这个问题会不会出现
这个问题很好解决,现在这个阶段,暂时会修改 scripts 中的命令行参数,去设置成 development 这个开发模式:
{
"scripts": {
"build": "webpack --mode=development"
}
}
同样再运行 npm run build
,就发现,报错信息居然少了一个:
webpack 5.41.0 compiled with 3 errors in 103 ms
最后一个 ERROR in bundle.js from Terser 居然消失了。那也就是说,现在剩下的 3 个报错都是开发时的报错,那就可以着手准备开放的 loader 和 plugin 的实现了。
另外,这个时候虽然还报错,但是 dist 目录已经能够显示出来了,证明 webpack 至少运行过一遍,并且导出了打包文件——这次可以确认 webpack 的安装和基础配置都没有问题了:
vue loader 是 webpack 的插件,这里的配置也都是跟着官方文档实现的。
1、安装
vue-loader
和vue-template-compiler
npm install -D vue-loader vue-template-compiler
# 突然意识到 cannot find Vue 的错误是因为我没有下载 package.json 里面列举的 Vue
# 于是重新做一次下载,将需要的依赖包下载好
npm install
2、按照官方文档的内容,重新编写
webpack.config.js
的内容
// 新增内容
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
// 新增内容
module: {
rules: [{ test: /\.vue$/, loader: 'vue-loader' }],
},
plugins: [new VueLoaderPlugin()],
};
3、继续跟着官方文档,下载和安装所需要的依赖以及重新编写
webpack.config.js
# babel 负责解析 JavaScript
npm install -D babel-loader @babel/core
# 其他两个负责解析CSS
npm install -D vue-style-loader css-loader
# 这也是必须的插件,否则会报错
# 官方文档里没有列出来,如果你那里出现不同的报错,一定要看报错信息
npm i -D @vue/cli-plugin-babel
// 新增内容
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
// module里面的东西为新增内容
module: {
rules: [
// 解析Vue文件
{ test: /\.vue$/, loader: 'vue-loader' },
// 它会应用到普通的 `.js` 文件
// 以及 `.vue` 文件中的 `