webpack高级概念Develoment 和 Production 不同环境的配置 (系列四)
因为在不同的环境下,webpack的配置稍微有点区别,如果我们需要在不同的换将下切换,就得重复修改webpack.config.js配置,这是很麻烦而且还容易改错,所以我们需要把配置文件进行拆分。
在项目根目录下新建build文件夹,然后在build文件夹中新建 webpack.dev.js
、 webpack.prod.js
和 webpack.base.js
三个文件
webpack.dev.js
:是开发环境
webpack.prod.js
:是生产环境
webpack.base.js
:是开发环境和生产环境都用到的共同配置
这几个文件之间的结合靠'webpack-merge'这个插件。
安装
npm i webpack-merge -D
开发配置
//webpack.dev.js const webpack=require('webpack') const merge = require('webpack-merge')
//引入公共的webpack配置 const baseConfig=require('./webpack.base') const devConfig={ mode: 'development', devtool: 'cheap-module-eval-source-map',
//热模块更新,开发环境独有 plugins: [ new webpack.HotModuleReplacementPlugin() ],
//树摇配置,开发环境默认没有,需要配置 optimization: { usedExports: true },
//自启服务 devServer: { contentBase: './dist', // open: true, //自动打开浏览器 // port: 8080, hot: true, //启用webpack的热模块替换功能 //hotOnly: true //devServer.hot在没有页面刷新的情况下启用热模块替换作为构建失败时的后备 } } //将公告配置和开发配置合并暴露出去 module.exports=merge(baseConfig,devConfig)
生产配置
//webapck.prod.js const merge = require('webpack-merge') const baseConfig=require('./webpack.base') const prodConfig={ mode: 'production', devtool: 'cheap-module-source-map' } module.exports=merge(baseConfig,prodConfig)
但是这两个文件还有大量重复的代码,新建 webpack.base.js
//webpack.base.js const path = require('path') const htmlWebpackPlugin = require('html-webpack-plugin') const cleanWebpackPlugin = require('clean-webpack-plugin') module.exports={ entry: { main: './src/index.js' }, output: { filename: '[name].js', path: path.resolve(__dirname,'dist') }, module: { rules:[ { test: /\.(png|jpg|gif)$/, use: { loader: 'url-loader', options: { name: '[name].[ext]', outputPath: 'images/', limit: 2048 } } }, { test: /\.css$/, use:[ 'style-loader', 'css-loader', 'postcss-loader' ] }, { test: /\.scss$/, use:[ 'style-loader', { loader: 'css-loader', options: { importLoaders: 2, modules: true } }, 'sass-loader', 'postcss-loader' ] }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' } ] }, plugins: [ new htmlWebpackPlugin({ template: './index.html' }), new cleanWebpackPlugin(), ] }
修改 package.json
的 script
:
./build/webpack.dev.js 配置文件路劲
{ "scripts": { "dev": "webpack-dev-server --config ./build/webpack.dev.js", "build": "webpack --config ./build/webpack.prod.js" }, }
开发环境:运行 npm run dev
,打开浏览器访问 http://localhost:8080/
就可以看到结果,由于开启了devServer,打包的文件在内存运行
生产环境:运行 npm run build , 生成了dist打包文件,可将dist文件放在服务器上
打包文件dist路劲配置
在项目根目录下新建build文件夹,然后在build文件夹中新建 webpack.dev.js
、 webpack.prod.js
和 webpack.base.js
三个文件,因为webpack配置文件路径变了,所以
输出的打包文件路劲要改变,打包文件dist夹路劲是和配置文件webpack.dev.js同级的
配置开发环境生成本地打包文件,package.json配置,
"scripts": { "dev-build": "webpack --config ./build/webpack.dev.js", "dev": "webpack-dev-server --config ./build/webpack.dev.js", "build": "webpack --config ./build/webpack.prod.js" },
在webpack.base.js中修改output,CleanWebpackPlugin配置(每次打包前清除旧的打包文件)
output: { filename: '[name].js',
//__dirname绝对路径默认与webpack.dev.js同级,然后走到lesson根路劲下的dist路劲打包 path: path.resolve(__dirname, '../dist') } plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html' }),
//然后删除dist打包文件夹 new CleanWebpackPlugin(['dist'], {
//__dirname默认与webpack.dev.js同级,回到根路劲,然后删除dist打包文件夹 root: path.resolve(__dirname, '../') }) ],
运行npm run dev-build, 看下dist文件夹是否在跟路劲lesson下,以及重新打包,旧的dist文件夹是否会重新清除(前提清除的路劲要正确)
常用的生产和开发webpack配置
webapck.common.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const webpack = require('webpack'); module.exports = { entry: { main: './src/index.js', }, resolve: { extensions: ['.js', '.jsx'], alias: { child: path.resolve(__dirname, '../src/a/b/c/child') } }, module: { rules: [{ test: /\.jsx?$/, include: path.resolve(__dirname, '../src'), use: [{ loader: 'babel-loader' }] }, { test: /\.(jpg|png|gif)$/, use: { loader: 'url-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'images/', limit: 10240 } } }, { test: /\.(eot|ttf|svg)$/, use: { loader: 'file-loader' } }] }, plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html' }), new CleanWebpackPlugin(['dist'], { root: path.resolve(__dirname, '../') }) ], optimization: { runtimeChunk: { name: 'runtime' }, usedExports: true, splitChunks: { chunks: 'all', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10, name: 'vendors.js', } } } }, performance: false, output: { path: path.resolve(__dirname, '../dist') } }
webpack.prod.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const merge = require('webpack-merge'); const commonConfig = require('./webpack.common.js'); const prodConfig = { mode: 'production', devtool: 'cheap-module-source-map', module: { rules:[{ test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { importLoaders: 2 } }, 'sass-loader', 'postcss-loader' ] }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ] }] }, optimization: { minimizer: [new OptimizeCSSAssetsPlugin({})] }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', chunkFilename: '[name].chunk.css' }) ], output: { filename: '[name].[contenthash].js', chunkFilename: '[name].[contenthash].js' } } module.exports = merge(commonConfig, prodConfig);
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 }, module: { rules: [{ test: /\.scss$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 2 } }, 'sass-loader', 'postcss-loader' ] }, { test: /\.css$/, use: [ 'style-loader', 'css-loader', 'postcss-loader' ] }] }, plugins: [ new webpack.HotModuleReplacementPlugin() ], output: { filename: '[name].js', chunkFilename: '[name].js', } } module.exports = merge(commonConfig, devConfig);