这篇文章,将一步一步慢慢让我们熟悉通过webpack自己手动配置dev.prod.test等各种环境。
webpack版本基于4.0+(目前webpack是5+)如果在运行过程中出现报错,请参考案例中的webpack三件套版本
第一步,我们要实现一个最简单的功能。
(1)通过运行npm run dev可以实现保存时热更新代码。
(2)通过运行 npm run build 可以实现打包
第一个功能的时候我们要借助wenpack-dev-server,第二个功能则需要借助webpack提供的打包命令
项目结构
---package.json
----src
-----main.js
---dist
---webpack.config.js
接下来我们安装依赖 (可以注意下版本.默认安装的webpack是5.+版本。这会导致webpack-dev-server不兼容跑不起来)
"clean-webpack-plugin": "^3.0.0",
"html-webpack-plugin": "^4.5.0",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
接下来我们在根目录下新建一个webpack.config.js文件,这个文件是我们的基础配置文件,我们生产。开发和测试环境都可以基于它做一些更改
webpack.base.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
entry: {
index: "./src/main.js"
},
output: {
path: path.resolve(__dirname, "./dist"),
filename: "bundle.js"
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
curEnv: process.env.NODE_ENV,
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["./dist"]
})
]
}
要想打包,我们还需要给package.json配置一些命令,如下:
"scripts": {
"dev": "cross-env webpack-dev-server --config ./webpack.config.js",
"build": "cross-env webpack --config ./webpack.config.js"
},
这两个命令的核心就是红色部分,npm run dev 是依靠webpack-dev-server跑起来的,npm run build打包命令则是依靠webpack本身webpack这个命令来实现的。
我们完成了第一部,实现了我们最初要的效果
2 我们要进一步考虑一个问题,在真实的项目场景中,我们经常会有一个开发环境,一个生产环境,在上线之前,我们要有一个预生产环境。我们需要在预生产环境,
在这里面我们要开启source-map调试等等。
至此,我们是时候来给他们单独分区开来,单独配置了。到这一步,我们需要重新更改我们的项目结构
---package.json
----src
-----main.js
---dist
---webpackConfig
---webpack.base.config.js //webpack公共配置
----webpack.dev.config.js //单独对dev的webpack配置
---- webpack.prod.config.js //单独对production的webpack配置
---webpack.test.config //单独对test的webpack配置
----envConfig
---dev.js
---prod.js
----test.js
我们先对webpackConfig文件夹做一些配置
----webpack.base.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
module.exports = {
entry: {
index: "./src/main.js"
},
output: {
path: path.resolve(__dirname, "../dist"),
filename: "bundle.js"
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
curEnv: process.env.NODE_ENV,
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ["./dist"]
})
]
}
----webpack.dev.config .js
const baseConfig = require("./webpack.config")
const { merge } = require("webpack-merge")
const webpack = require("webpack")
const dev = require("../envConfig/dev.js")
module.exports = merge(baseConfig, {
mode: "development",
plugins: [
new webpack.DefinePlugin({
'process.env': dev,
})
],
devtool: "inline-source-map",
devServer: {
port: 9000,
open: true, // 自动开启浏览器
hot: true,
}
})
----webpack.prod.config.js
const baseConfig = require("./webpack.config")
const { merge } = require("webpack-merge")
const webpack = require("webpack")
const prod = require("../envConfig/prod.js")
module.exports = merge(baseConfig, {
mode: "production",
plugins: [
new webpack.DefinePlugin({
'process.env': prod,
})
],
devtool: "none",
})
----webpack.test.config.js
const baseConfig = require("./webpack.config")
const { merge } = require("webpack-merge")
const webpack = require("webpack")
const test = require("../envConfig/test.js")
module.exports = merge(baseConfig, {
mode: "production",
plugins: [
new webpack.DefinePlugin({
'process.env': test,
})
],
devtool: "source-map",
})
这三个文件我们是借助了webpack.DefinePlugin插件。实现在node中设定了几个全局变量。然后dev环境我们开启了devServer,
test环境我们开启了source-map,proudction环境我们则关闭了source-map,作了一个简单的区分而已,
DefinePlugin
允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin
的用处
注意 我们每个js文件都引入了const test = require("../envConfig/test.js") (test,dev,prod)那我们肯定是需要对envConfig文件夹下三个js文件做相应设置
---envConfig
---dev.js
module.exports = {
NODE_ENV: '"development"',
BASE_API: '"http://development.com"'
}
---prod.js
module.exports = {
NODE_ENV: '"production"',
BASE_API: '"http://production.com"'
}
---test.js
module.exports = {
NODE_ENV: '"test"',
BASE_API: '"http://test.com"'
}
走完这一步,我们就需要给test,dev,prod配置不同的命令来打包。所以此时我们更改我们的package.json的script
"scripts": {
"dev": "cross-env NODE_ENV='development' webpack-dev-server --config ./webpackConfig/webpack.dev.config.js",
"test": "cross-env NODE_ENV='test' webpack --config ./webpackConfig/webpack.test.config.js",
"build": "cross-env NODE_ENV='production' webpack --config ./webpackConfig/webpack.prod.config.js"
},
ok,完成了。我们试着测试下test环境和prod环境。我们在main.js文件中打印下当前的环境。打包以后看执行的是否正常
main.js
console.log("当前的环境是", process.env.NODE_ENV)
我们分别执行下npm run test 、npm run build,然后在dist文件夹下看看console.log打印的值。正常则说明成功了。
当然,我们也可以把 process.env.NODE_ENV的值通过htmlwebpackplugin传递到index.html页面。让他展示出来,看看是否正确。
我们可以先在webpck.base.config.js文件中传递一个变量curEnv,然后在index.html模板文件中通过htmlWebpackPlugin.options.curEnv去接收他,
注意,不是HtmlWebpackPlugin(不是该插件的实例对象,而是htmlWebpackPlugin本身)
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
curEnv: process.env.NODE_ENV,//这里可以是你传递出去的任意值
})
]
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
<h2>webpack</h2>
<h3><%= htmlWebpackPlugin.options.curEnv %></h3>
</body>
</html>
这样我们最后npm run test或者npm run build 以后就可以在dist页面中看到当前的环境。
这里特别特别要注意几点:
(1)环境配置一定要用标准的json格式,用单双引号括起来。单独“”webpack会把它识别为变量
(2)对应webpack.config.js的mode选项。只有“developmnet”,“production”,“none”三个值。对于test环境。我们也应该设置其mode为“production”,如果设置为test。则会报错