webpack
打包的过程中,怎么使用一些环境变量呢?
-
我们之前分了3个配置文件
-
然后我们在
package.json
这个包文件里,定义了3个命令
分别是开发环境的命令dev
打包生成开发环境下代码的命令dev-build
线上代码生成的命令build
这三个命令会借助2个配置文件,来帮助我们完成去完成对应的打包,分别是开发环境的配置文件
webpack.dev.js
和线上环境的配置文件webpack.prod.js
现在我们可以通过另外一种形式对配置文件进行变更
- 先修改
webpack.dev.js
,修改之前
const webpack = require('webpack');
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const devConfig = {
mode: "development",
devtool:'cheap-module-eval-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true, //让webpack开启 Hot Module Replace 的功能
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: '[name].js',
chunkFilename:'[name].js',
}
}
//最终导出的是 devConfig 和 commonConfig 结合的配置
module.exports = merge(commonConfig,devConfig)
- 修改之后,导出的就是dev环境的配置文件
const webpack = require('webpack');
const devConfig = {
mode: "development",
devtool:'cheap-module-eval-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
hot: true, //让webpack开启 Hot Module Replace 的功能
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
output: {
filename: '[name].js',
chunkFilename:'[name].js',
}
}
module.exports = devConfig;
- 然后再修改
webpack.prod.js
,修改之前
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const prodConfig = {
mode: "production",
// devtool: 'cheap-module-source-map'
output: {
filename: '[name].[contenthash].js',
chunkFilename:'[name].[contenthash].js',
}
}
//最终导出的是 prodConfig 和 commonConfig 结合的配置
module.exports = merge(commonConfig,prodConfig)
- 修改后,导出的就只是线上环境的配置文件
const prodConfig = {
mode: "production",
// devtool: 'cheap-module-source-map'
output: {
filename: '[name].[contenthash].js',
chunkFilename:'[name].[contenthash].js',
}
}
module.exports = prodConfig;
- 然后修改
webpack.common.js
,修改之前
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
main: "./src/index.js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
}, {
loader:'imports-loader?this=>window'
}]
},
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
limit: 10240
}
}
},
{
test: /\.(eot|ttf|svg|woff)$/,
use: {
loader: 'file-loader'
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template:'./src/index.html'
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[name].chunk.css"
}),
new webpack.ProvidePlugin({
$: 'jquery',
_join:['lodash','join']
})
],
optimization: {
runtimeChunk: {
name:'runtime'
},
usedExports: true ,
splitChunks: {
chunks: "all",
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name:'vendors'
}
}
},
minimizer:[new OptimizeCSSAssetsPlugin({})]
},
performance:false,
output: {
path:path.resolve(__dirname,'../dist')
}
}
- 修改后
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const webpack = require('webpack');
const merge = require('webpack-merge'); //新增
const devConfig = require('./webpack.dev.js'); //新增
const prodConfig = require('./webpack.prod.js'); //新增
const commonConfig = {
entry: {
main: "./src/index.js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
}, {
loader:'imports-loader?this=>window'
}]
},
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash].[ext]',
outputPath: 'images/',
limit: 10240
}
}
},
{
test: /\.(eot|ttf|svg|woff)$/,
use: {
loader: 'file-loader'
}
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'sass-loader',
'postcss-loader'
]
},{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template:'./src/index.html'
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename:"[name].chunk.css"
}),
new webpack.ProvidePlugin({
$: 'jquery',
_join:['lodash','join']
})
],
optimization: {
runtimeChunk: {
name:'runtime'
},
usedExports: true ,
splitChunks: {
chunks: "all",
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name:'vendors'
}
}
},
minimizer:[new OptimizeCSSAssetsPlugin({})]
},
performance:false,
output: {
path:path.resolve(__dirname,'../dist')
}
}
//原来我们是导出一个对象,现在我们导出一个函数,这个函数接受一个全局变量env
module.exports = (env) => {
//我们做一个判断,如果外部传递给我了一个全局变量env,而且传递给我了一个production属性,那就说明现在是一个线上环境
if (env && env.production) {
return merge(commonConfig,prodConfig)
} else {
//否则就是开发环境
return merge(commonConfig,devConfig)
}
}
- 最终
webpack.common.js
导出的是线上环境的配置,还是开发环境的配置,
取决于外部传给webpack.common.js
的全局变量env
以及env
里的一个属性production
所以,我们打包的时候,就要往webpack.common.js
文件里去传递变量。怎么传呢? 修改我们的package.json
文件。
如果我们打包生成开发环境的代码
dev-build
,
我们直接用webpack.common.js
这个配置文件,
我们就不传全局变量env
,
不传变量webpack.common.js
导出的时候,
就会走导出开发环境配置的逻辑如果我们直接运行开发环境
dev
,
们直接用webpack.common.js
这个配置文件就行了如果我们打包生成线上的代码,
这个时候用的也是webpack.common.js
这个配置文件,
而且需要传全局变量env
和它的属性production
直接这样写
--env.production
的意思是,
通过全局变量向webpack
的配置文件里,
传递一个属性production
,它的值默认就是true
配置完后,我们保存并运行一下,看下效果
-
运行
npm run dev-build
,打包生成了这3个文件- 运行
npm run build
,则生成这几个文件
- 跟我们之前分开,通过不同的配置文件进行打包,产生的最终的代码的结果,没有任何的差异。
只不过这样去打包,我们不是通过不同的配置文件来生成不同的打包结果,
而是通过一个配置文件进行代码的生成,只不过通过一个变量,来控制最终到底怎么去打包。
- 运行
当然,全局变量还可以这样传 直接传一个--env production
,这样去传变量的话,那么webpack.common.js
接受的就不是env
了,而是接收production
我们还可以这样写--env production===abc
- 所以外部传递的全局变量的值,我们可以自由的去切换。可以根据不同的值,去做不同处理
链接:https://www.jianshu.com/p/9325ba792af8