公司有一个19年的老项目,使用webpack3打包编译,然后经过后续一系列不太合规的维护,存在很多问题
1、运行环境配置
2、编译时间
3、热更新时间
这种情况遇到的同学应该都知道,改个样式等半天的感觉,思路全被打乱了,这使我们的开发效率尤其低下,抽空来做一下升级
先看看升级之后的成果(有些业务代码的错误没改,可以先忽略),编译时间减少了35%,热更新时间减少83.7%,热更新时间只有1s多,这效率瞬间就上来了
编译时间
热更新时间
开始升级
网上找了很多资料,其实思路都是一样的
- 先把webpack相关升级,接着把各个包升级到兼容webpack5的版本
- 升级配置项,有些配置项是webpack3的写法,webpack5已经弃用了
- 最后根据控制台报错逐步完善(这一步各个项目安装依赖不一样,报错可能也不一样)
项目结构
css
build
|-------util.js
|-------webpack.base.js
|-------webpack.dev.conf.js
|-------webpack.prod.conf.js
webpack升级
arduino
// 先卸载webpack相关
npm uninstall webpack webpack-dev-server webpack-cli
// 安装webpack最新版本
npm install webpack webpack-dev-server webpack-cli
项目其他依赖升级,可以使用命令行工具完成
arduino
npm install -g npm-check-updates
// 然后直接输入,你会发现需要升级的包
npm-check-updates
// 接着使用下面命令进行升级
ncu -u
配置项升级
从这里开始你就可以运行指令来检查webpack问题了,比如我这边的npm run dev
启动脚本
检查自己的package.json
json
"dev": "cross-env BABEL_ENV=development NODE_ENV=dev01 webpack-dev-server --inline --progress --config build/webpack.dev.conf.js"
npm run dev的时候会报错,这里有两个问题
- webpack在升级到4的时候,启动脚本就从webpack-dev-server变成了webpack serve
- 不支持选项
--inline
,在webpack3中这个配置是让所有的模块内联到主模块中,好处当然是减少了 HTTP 请求的数量,坏处一大堆。Webpack 4 以后的版本默认启用了代码分割功能,这可以自动地将应用程序分割成多个较小的代码块,并在需要时按需加载这些代码块。因此,使用--inline
选项可能不再是必要的
配置文件修改
webpack.base.conf.js
1、解析vue文件
js
const { VueLoaderPlugin } = require('vue-loader')
let webpackConfig = {
plugins: [
new VueLoaderPlugin(),
]
}
2、资源解析
webpack内置了url-loader,file-loader等等,资源解析直接调整使用使用type:'asset'
js
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 10 * 1024 // 10kb
}
},
generator: {
filename: utils.assetsPath('img/[name].[hash:7].[ext]')
}
}
webpack.dev.conf.js
1、webpack-merge要解构出来
js
const { merge } = require('webpack-merge')
2、extract-text-webpack-plugin
和optimize-css-assets-webpack-plugin
已经过时了需要由mini-css-extract-plugin
和css-minimizer-webpack-plugin
来代替
3、NamedModulesPlugin
已过时,由optimization的moduleIds进行替换
js
optimization: {
moduleIds: 'named' // webpack5 采用此方式代替 NamedModulesPlugin
},
4、devServer改动很大,可以参考官网改动
我自己的修改
js
{
// webpack3下面的配置都收敛到client中了
// clientLogLevel: 'warning',
// overlay: config.dev.errorOverlay ? {
// warnings: false,
// errors: true,
// } : false,
// progress: true
client: {
logging: 'warn',
overlay: config.dev.errorOverlay ? {
warnings: false,
errors: true,
} : false,
progress: true,
},
historyApiFallback: true,
hot: true,
host: "0.0.0.0",
port: process.env.PORT || config.dev.port,
open: true,
// publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
// quiet: true, // necessary for FriendlyErrorsPlugin
// watchOptions: {
// poll: config.dev.poll,
// },
// https: false,
},
5、由于vue-loader
升级了,所以之前css如果使用/deep/可能出错,相应调整一下
6、到这一步再运行npm run dev的时候又报了一个问题,所有的依赖包都报找不到vue
webpack运行时,依赖包会从当前目录开始查找node_modules,因为我们的webpack.dev.conf和node_modules没在同级就会抛出错误,用下面方式解决
js
resolve: {
alias: {
'vue$': path.resolve(__dirname, '../node_modules/vue/dist/vue.esm-bundler.js') // 根据你的实际情况调整路径
}
}
7、另外项目中使用了vux-loader,导致报错,因为没有兼容webpack5的版本,需要用其他插件替换
此时项目已经升级差不多了,剩下的就是解决报错问题了,项目语法问题解决语法问题,依赖问题就找webpack5兼容的包,或者用其他包替换
再次回到一开始的环境配置问题
如何让我们切换环境的时候,不需要配置很多指令呢
第一个方案肯定就是env文件
.env文件是一个全局默认配置文件,在所有的环境中都会被加载和合并。它用于存储环境变量,可以在开发、测试、生产等不同环境下配置不同的变量值,以便在项目中使用。
在.env文件中,可以使用键值对的形式创建变量,其中键名必须以VUE_APP_开头。例如,VUE_APP_BASE_API = '/api'。
根据项目的需要,可以在不同的环境下创建.env文件,例如.env.development、.env.production等。这些文件可以用于配置针对不同环境的变量值。
在项目中使用.env文件时,可以通过process.env对象来访问这些变量。例如,使用console.log(process.env.VUE_APP_BASE_API)可以输出VUE_APP_BASE_API的值。
第二种方法,根据环境给命令行传参数,类似npm run dev -- NODE_ENV=fat03 在页面中打印process.argv就会得到我们传递的参数