该文章创建于 793 天前,请以最新文章为准!
前言
若文章有误,欢迎读者留言反馈
💻Installation
1
| git clone https://github.com/coding327/learn_webpack5.git
|
webpack-完结篇
应该是webpack5
最后一篇了,主要来说一下环境分离
对于我们的项目,主要被分为开发环境和生产环境,运行我们目前的项目的时候有一个弊端,当我们进行打包【生产环境】时,它会加载webpack.config.js
文件,但是这个文件里面也有很多是开发环境的配置,如mode
为development
,devtool
,那么相当于他也会跑一遍,当我们运行本地服务【开发环境】时也有一些配置不合适,如清除打包的插件,复制功能插件
所以我们应该对开发环境和生产环境做一个分离
在项目根目录创建一个config
文件夹,然后分别创建以下三个文件:
webpack.dev.config.js
: 开发环境配置文件;
webpack.prod.config.js
: 生产环境配置文件;
webpack.comm.config.js
: 公共配置文件;
回到package.json中,针对不同环境指定不同的配置文件
1 2 3 4 5 6 7 8
| { ... "scripts": { "build": "webpack --config ./config/webpack.prod.config.js", "serve": "webpack serve --config ./config/webpack.dev.config.js" }, ... }
|
接着就是分离文件内容了,首先我会把原来的webpack.config.js
文件里的内容复制,粘贴到webpack.comm.config.js
文件中,注意把所有的功能都先打开,这里我们之前注释的复制功能插件给它取消注释,然后从导出的对象里面开始读,哪些是公共的就留着,不是公共的就剪切掉【注意不是删除啊!!!】,剪切后放到对应环境的配置文件中,注意写个module.exports = {}
,把它放到要导出的这个对象里面;接着判断另外一个环境是否需要,需要这个配置项就粘贴到另外一个环境中,更改为该环境的配置即可【不需要就不用粘贴】,注意也要写个module.exports = {}
,把它放到要导出的这个对象里面。剩下的配置项都是这么一系列操作,最后把这些配置项需要的模块要导入进来。
webpack.comm.config.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| const path = require('path')
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { DefinePlugin } = require("webpack")
const { VueLoaderPlugin } = require("vue-loader/dist/index")
module.exports = { target: "web", entry: "./src/main.js", output: { path: path.resolve(__dirname, './build/'), filename: "js/main.js", }, resolve: { extensions: [".js", ".json", ".wasm", ".vue", ".ts", ".jsx", ".tsx"], alias: { "@": path.resolve(__dirname, "./src"), "js": path.resolve(__dirname, "./src/js") } }, module: { rules: [ { test: /\.css$/,
use: [ "style-loader", "css-loader", "postcss-loader" ] }, { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }, { test: /\.(jpe?g|png|gif|svg)$/, type: 'asset', generator: { filename: "img/[name]_[hash:6][ext]" }, parser: { dataUrlCondition: { maxSize: 10 * 1024 } } }, { test: /\.(eot|ttf|woff2?)$/, type: 'asset/resource', generator: { filename: 'font/[name]_[hash:6][ext]', } }, { test: /\.js$/, loader: "babel-loader" }, { test: /\.vue$/, loader: "vue-loader" }, {}, ] }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", title: "巧克力真美味" }), new DefinePlugin({ BASE_URL: '"./"', __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }), new VueLoaderPlugin() ] }
|
webpack.dev.config.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| module.exports = { mode: "development", devtool: "source-map", devServer: { static: "./public", hot: true, port: 7777, open: true, proxy: { "/api": { target: "http://localhost:8888", pathRewrite: { "^/api": "" }, secure: false, changeOrigin: true, } } }, }
|
webpack.prod.config.js
文件代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
module.exports = { mode: "production", plugins: [ new CleanWebpackPlugin(), new CopyWebpackPlugin({ patterns: [ { from: "public", to: "./", globOptions: { ignore: [ "**/index.html" ] } } ] }), ] }
|
以上就完成了将一个配置文件分离为三个配置文件,但是我们还得把公共的合并到开发、生产配置文件中
这里我们可以使用webpack
官方提供的一个合并插件:webpack-merge
安装该插件
1
| npm install webpack-merge -D
|
进入webpack.dev.config.js
文件中,做合并:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.comm.config")
module.exports = merge(commonConfig, { mode: "development", devtool: "source-map", devServer: { static: "./public", hot: true, port: 7777, open: true, proxy: { "/api": { target: "http://localhost:8888", pathRewrite: { "^/api": "" }, secure: false, changeOrigin: true, } } }, })
|
进入webpack.prod.config.js
文件中,做合并:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.comm.config")
module.exports = merge(commonConfig, { mode: "production", plugins: [ new CleanWebpackPlugin(), new CopyWebpackPlugin({ patterns: [ { from: "public", to: "./", globOptions: { ignore: [ "**/index.html" ] } } ] }), ] })
|
配置完,然后就是路径问题了,除了entry
【这个会专门拿出来说一下】、BASE_URL
、HtmlWebpackPlugin
模板路径、复制功能插件【这个是赋值】和static
等几个特殊的路径不用改动,其余基本上,路径都会有所变动
这里关于entry
,引入一个入口文件解析
入口文件解析
我们之前编写入口文件的规则是这样的: /src/index.js
,但是如果我们的配置文件所在的位置变成了config
目录,我们是否应该变成../src/index.js
呢?
- 如果我们这样编写,会发现是报错的,依然要写成
./src/index.js
;
- 这是因为入口文件其实是和另一个属性是有关的
context
;
context
的作用是用于解析入口( entry point
)和加载器( loader
) :
- 官方说法︰ 默认是当前路径(但是经过测试,默认应该是
webpack
的启动目录)
- 另外推荐在配置中传入一个值;
1 2 3 4 5
| module.exports = { context: path.resolve(__dirname, "./"), entry: "../src/index.js" }
|
所以说entry
其实是和webpack启动目录即package.json
所在目录有关,不需要改动路径
接着重新打包测试,浏览器显示正常
本地服务运行,浏览器也显示正常
由于路径改动,这里我也把三个文件路径改动后的配置代码放在下方
webpack.comm.config.js
文件代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| const path = require('path')
const HtmlWebpackPlugin = require("html-webpack-plugin")
const { DefinePlugin } = require("webpack")
const { VueLoaderPlugin } = require("vue-loader/dist/index")
module.exports = { target: "web", entry: "./src/main.js", output: { path: path.resolve(__dirname, '../build/'), filename: "js/main.js", }, resolve: { extensions: [".js", ".json", ".wasm", ".vue", ".ts", ".jsx", ".tsx"], alias: { "@": path.resolve(__dirname, "../src"), "js": path.resolve(__dirname, "../src/js") } }, module: { rules: [ { test: /\.css$/,
use: [ "style-loader", "css-loader", "postcss-loader" ] }, { test: /\.less$/, use: [ "style-loader", "css-loader", "less-loader" ] }, { test: /\.(jpe?g|png|gif|svg)$/, type: 'asset', generator: { filename: "img/[name]_[hash:6][ext]" }, parser: { dataUrlCondition: { maxSize: 10 * 1024 } } }, { test: /\.(eot|ttf|woff2?)$/, type: 'asset/resource', generator: { filename: 'font/[name]_[hash:6][ext]', } }, { test: /\.js$/, loader: "babel-loader" }, { test: /\.vue$/, loader: "vue-loader" }, {}, ] }, plugins: [ new HtmlWebpackPlugin({ template: "./public/index.html", title: "巧克力真美味" }), new DefinePlugin({ BASE_URL: '"./"', __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }), new VueLoaderPlugin() ] }
|
webpack.dev.config.js
文件代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.comm.config")
module.exports = merge(commonConfig, { mode: "development", devtool: "source-map", devServer: { static: "./public", hot: true, port: 7777, open: true, proxy: { "/api": { target: "http://localhost:8888", pathRewrite: { "^/api": "" }, secure: false, changeOrigin: true, } } }, })
|
webpack.prod.config.js
文件代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.comm.config")
module.exports = merge(commonConfig, { mode: "production", plugins: [ new CleanWebpackPlugin(), new CopyWebpackPlugin({ patterns: [ { from: "./public", to: "./", globOptions: { ignore: [ "**/index.html" ] } } ] }), ] })
|
结语
至此,webpack5
告一段落了❤