15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > Webpack基础应用篇-[13] 1.10 拆分开发环境和生产环境配置

Webpack基础应用篇-[13] 1.10 拆分开发环境和生产环境配置

时间:2023-05-28 23:45:01 | 来源:网站运营

时间:2023-05-28 23:45:01 来源:网站运营

Webpack基础应用篇-[13] 1.10 拆分开发环境和生产环境配置:现在,我们只能手工的来调整 mode选项,实现生产环境和开发环境的切换,且很多配置在生产环境和开发环境中存在不一致的情况,比如开发环境没有必要设置缓存,生产环境还需要设置公共路径等等。

本节介绍拆分开发环境和生产环境,让打包更灵活。

1.10.1 公共路径

publicPath 配置选项在各种场景中都非常有用。你可以通过它来指定应用程序中所有资源的基础路径。

import webpack from 'webpack';// 尝试使用环境变量,否则使用根路径const ASSET_PATH = process.env.ASSET_PATH || '/';export default { output: { publicPath: ASSET_PATH, }, plugins: [ // 这可以帮助我们在代码中安全地使用环境变量 new webpack.DefinePlugin({ 'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH), }), ],};11-multiple-env/webpack.config.js

//...import webpack from 'webpack';// 尝试使用环境变量,否则使用根路径const ASSET_PATH = process.env.ASSET_PATH || '/';export default {output: { //... publicPath: ASSET_PATH,},plugins: [ // 这可以帮助我们在代码中安全地使用环境变量 new webpack.DefinePlugin({ 'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH), }), //... ],};

Automatic publicPath

有可能你事先不知道 publicPath 是什么,webpack 会自动根据 import.meta.urldocument.currentScriptscript.src 或者 self.location 变量设置 publicPath。你需要做的是将 output.publicPath 设为 'auto'

module.exports = { output: { publicPath: 'auto', },};请注意在某些情况下不支持 document.currentScript,例如:IE 浏览器,你不得不引入一个 polyfill,例如 currentScript Polyfill

1.10.2 环境变量

想要消除 webpack.config.js 在 开发环境 和 生产环境 之间的差异,你可能需要环境变量(environment variable)。

webpack 命令行 环境配置 的 --env 参数,可以允许你传入任意数量的环境变量。而在 webpack.config.js 中可以访问到这些环境变量。例如,--env production--env goal=local

npx webpack --env goal=local --env production --progress对于我们的 webpack 配置,有一个必须要修改之处。通常,module.exports 指向配置对象。要使用 env 变量,你必须将 module.exports 转换成一个函数:

11-multiple-env/webpack.config.js

//...module.exports = (env) => {return {//...// 根据命令行参数 env 来设置不同环境的 modemode: env.production ? 'production' : 'development',//...}}

1.10.3 拆分配置文件

目前,生产环境和开发环境使用的是一个配置文件,我们需要将这两个文件单独放到不同的配置文件中。如webpack.config.dev.js(开发环境配置)和 webpack.config.prod.js(生产环境配置)。在项目根目录下创建一个配置文件夹 config 来存放他们。

webpack.config.dev.js 配置如下:

11-multiple-env/config/webpack.config.dev.js

const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const toml = require('toml')const yaml = require('yaml')const json5 = require('json5')module.exports = {entry: {index: './src/index.js',another: './src/another-module.js'},output: {filename: 'scripts/[name].js',path: path.resolve(__dirname, './dist'),clean: true,assetModuleFilename: 'images/[contenthash][ext]'},mode: 'development',devtool: 'inline-source-map',plugins: [new HtmlWebpackPlugin({ template: './index.html', filename: 'app.html', inject: 'body'}),new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css'})],devServer: {static: './dist'},module: {rules: [ { test: //.png$/, type: 'asset/resource', generator: { filename: 'images/[contenthash][ext]' } }, { test: //.svg$/, type: 'asset/inline' }, { test: //.txt$/, type: 'asset/source' }, { test: //.jpg$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 4 * 1024 * 1024 } } }, { test: //.(css|less)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'] }, { test: //.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource' }, { test: //.(csv|tsv)$/, use: 'csv-loader' }, { test: //.xml$/, use: 'xml-loader' }, { test: //.toml$/, type: 'json', parser: { parse: toml.parse } }, { test: //.yaml$/, type: 'json', parser: { parse: yaml.parse } }, { test: //.json5$/, type: 'json', parser: { parse: json5.parse } }, { test: //.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ [ '@babel/plugin-transform-runtime' ] ] } } }]},optimization: {splitChunks: { cacheGroups: { vendor: { test: /[///]node_modules[///]/, name: 'vendors', chunks: 'all' } }}}}webpack.config.prod.js 配置如下:

11-multiple-env/config/webpack.config.prod.js

const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')const toml = require('toml')const yaml = require('yaml')const json5 = require('json5')module.exports = {entry: {index: './src/index.js',another: './src/another-module.js'},output: {filename: 'scripts/[name].[contenthash].js',// 打包的dist文件夹要放到上一层目录path: path.resolve(__dirname, '../dist'),clean: true,assetModuleFilename: 'images/[contenthash][ext]',publicPath: 'http://localhost:8080/'},mode: 'production',plugins: [new HtmlWebpackPlugin({ template: './index.html', filename: 'app.html', inject: 'body'}),new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css'})],module: {rules: [ { test: //.png$/, type: 'asset/resource', generator: { filename: 'images/[contenthash][ext]' } }, { test: //.svg$/, type: 'asset/inline' }, { test: //.txt$/, type: 'asset/source' }, { test: //.jpg$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 4 * 1024 * 1024 } } }, { test: //.(css|less)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'] }, { test: //.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource' }, { test: //.(csv|tsv)$/, use: 'csv-loader' }, { test: //.xml$/, use: 'xml-loader' }, { test: //.toml$/, type: 'json', parser: { parse: toml.parse } }, { test: //.yaml$/, type: 'json', parser: { parse: yaml.parse } }, { test: //.json5$/, type: 'json', parser: { parse: json5.parse } }, { test: //.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ [ '@babel/plugin-transform-runtime' ] ] } } }]},optimization: {minimizer: [ new CssMinimizerPlugin()],splitChunks: { cacheGroups: { vendor: { test: /[///]node_modules[///]/, name: 'vendors', chunks: 'all' } }}},//关闭 webpack 的性能提示performance: {hints:false}}拆分成两个配置文件后,分别运行这两个文件:

开发环境:

[felix] 10-multiple-env $ npx webpack serve -c ./config/webpack.config.dev.js生产环境:

[felix] 10-multiple-env $ npx webpack -c ./config/webpack.config.prod.js

1.10.4 npm 脚本

每次打包或启动服务时,都需要在命令行里输入一长串的命令。我们将父目录的 package.jsonnode_modulespackage-lock.json拷贝到当前目录下,

配置 npm 脚本来简化命令行的输入,这时可以省略 npx

11-multiple-env/package.json

{"scripts": {"start": "webpack serve -c ./config/webpack.config.dev.js","build": "webpack -c ./config/webpack.config.prod.js"}}开发环境运行脚本:

[felix] 10-multiple-env $ npm run start


[felix] 10-multiple-env $ npm run build

1.10.5 提取公共配置

这时,我们发现这两个配置文件里存在大量的重复代码,可以手动的将这些重复的代码单独提取到一个文件里,

创建 webpack.config.common.js,配置公共的内容:

11-multiple-env/config/webpack.config.common.js

const path = require('path')const HtmlWebpackPlugin = require('html-webpack-plugin')const MiniCssExtractPlugin = require('mini-css-extract-plugin')const toml = require('toml')const yaml = require('yaml')const json5 = require('json5')module.exports = {entry: {index: './src/index.js',another: './src/another-module.js'},output: {// 注意这个dist的路径设置成上一级path: path.resolve(__dirname, '../dist'),clean: true,assetModuleFilename: 'images/[contenthash][ext]',},plugins: [new HtmlWebpackPlugin({ template: './index.html', filename: 'app.html', inject: 'body'}),new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css'})],module: {rules: [ { test: //.png$/, type: 'asset/resource', generator: { filename: 'images/[contenthash][ext]' } }, { test: //.svg$/, type: 'asset/inline' }, { test: //.txt$/, type: 'asset/source' }, { test: //.jpg$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 4 * 1024 } } }, { test: //.(css|less)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader'] }, { test: //.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource' }, { test: //.(csv|tsv)$/, use: 'csv-loader' }, { test: //.xml$/, use: 'xml-loader' }, { test: //.toml$/, type: 'json', parser: { parse: toml.parse } }, { test: //.yaml$/, type: 'json', parser: { parse: yaml.parse } }, { test: //.json5$/, type: 'json', parser: { parse: json5.parse } }, { test: //.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], plugins: [ [ '@babel/plugin-transform-runtime' ] ] } } }]},optimization: {splitChunks: { cacheGroups: { vendor: { test: /[///]node_modules[///]/, name: 'vendors', chunks: 'all' } }}},//关闭 webpack 的性能提示performance: {hints:false}}改写 webpack.config.dev.js:

11-multiple-env/config/webpack.config.dev.js

module.exports = {// 开发环境不需要配置缓存output: {filename: 'scripts/[name].js',},// 开发模式mode: 'development',// 配置 source-mapdevtool: 'inline-source-map',// 本地服务配置devServer: {static: './dist'}}修改 webpack.config.prod.js:

11-multiple-env/config/webpack.config.prod.js

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')module.exports = {// 生产环境需要缓存output: {filename: 'scripts/[name].[contenthash].js',publicPath: 'http://localhost:8080/'},// 生产环境模式mode: 'production',// 生产环境 css 压缩optimization: {minimizer: [ new CssMinimizerPlugin()]}}1.10.6 合并配置文件

配置文件拆分好后,新的问题来了,如何保证配置合并没用问题呢?webpack-merge 这个工具可以完美解决这个问题。

安装 webpack-merge:

[felix] felixcourses $ npm install webpack-merge -D创建 webpack.config.js,合并代码:

11-multiple-env/config/webpack.config.js

const { merge } = require('webpack-merge')const commonConfig = require('./webpack.config.common.js')const productionConfig = require('./webpack.config.prod.js')const developmentConfig = require('./webpack.config.dev')module.exports = (env) => {switch(true) {case env.development: return merge(commonConfig, developmentConfig)case env.production: return merge(commonConfig, productionConfig)default: throw new Error('No matching configuration was found!');}}---本章完---

关键词:环境,配置,生产,基础

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭