vwe中配置开发环境和生产环境
上面基本实现了一个Application前端了,但是通常来说,开发环境和生产环境来说是不同的,
比如
- 在开发环境中可以debug,查看源代码,但是在生产环境中是不被允许的
- 图片啥的在开发环境中可看,但是在生产环境中我们想用Base64加密后放在css中
- 由于开发环境中每次开发需要刷新,我们需要使用hot module reloading,但是在
生产环境中,明显不需要。
所以,我们需要做的是:
- 给开发环境定义一个webpack.config.js名字叫做webpack.dev.config.js
- 给生产环境定义一个webpack.config.js名字叫做webpack.prod.config.js
- 给开发环境定义一个server.js名字叫做server-dev.js
- 给生产环境定义一个server.js名字叫做server-prod.js
暂时不改变代码,当前目录如下:
src
server
server-dev.js
server-prod.js
webpack.dev.config.js
webpack.prod.config.js
webpack.server.config.js
注意:为什么要用这种方式而不是其他的聪明的方式来分开开发或者生产环境这是基于我个人的
风格,个人更加倾向于很显然的开发风格,代码更加易读。
现在,我们来更新webpack.server.config.js ,代码如下:
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
module.exports = (env, argv) => {
const SERVER_PATH = (argv.mode === 'production') ?
'./src/server/server-prod.js' :
'./src/server/server-dev.js'
return ({
entry: {
server: SERVER_PATH,
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
})
}
这里我们使用了webpack 4中可以通过命令行传递参数到config中的对外函数中,argv中有一个
'mode’属性来定义环境
module.exports = (env, argv) => {
const SERVER_PATH = (argv.mode === 'production') ?
'./src/server/server-prod.js' :
'./src/server/server-dev.js'
现在修改package.json中的脚本代码如下:
"scripts": {
"buildDev": "DEL /F /Q dist & webpack --mode development --config webpack.server.config.js & webpack --mode development --config webpack.dev.config.js",
"buildProd": "DEL /F /Q dist & webpack --mode production --config webpack.server.config.js & webpack --mode production --config webpack.prod.config.js ",
"start": "node ./dist/server.js"
},
编译开发环境的dist,执行
npm run buildDev
打开./dist/main.js或者浏览器下debug模式下的main.js,你可以看到整齐分行的代码。
编译生产环境的dist,执行
npm run buildProd
打开./dist/main.js或者浏览器下debug模式下的main.js,你可以看到一行丑陋的代码。
注意:这里我们只是为了证明webpack对于开发环境和生产环境的打包生成方式的不同点,这个时候webpack.dev.config.js和webpack.prod.config.js是一样的。
解析
产生的原因在于我们脚本传入的参数 --mode development和–mode production,webpack根据这个采用不同的打包方式。
让我们分别给开发环境和生产环境设计一些功能以便我们分开发和生产环境有些意义。正如我们上面所述,生成环境中
我们希望可以用BASE64加密图片到css文件中,但webpack中没有css小化插件,所以我们需要自己安装。
npm install --save-dev mini-css-extract-plugin uglifyjs-webpack-plugin optimize-css-assets-webpack-plugin url-loader
我们把 webpack.prod.config.js改成如下:
const path = require("path")
const HtmlWebPackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'web',
devtool: 'source-map',
// Webpack 4 does not have a CSS minifier, although
// Webpack 5 will likely come with one
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({})
]
},
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
},
{
// Loads images into CSS and Javascript files
test: /\.jpg$/,
use: [{loader: "url-loader"}]
},
{
// Loads CSS into a file when you import it via Javascript
// Rules are set in MiniCssExtractPlugin
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/html/index.html",
filename: "./index.html"
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
}
webpack.dev.config.js保持不变
const path = require("path")
const webpack = require('webpack')
const HtmlWebPackPlugin = require("html-webpack-plugin")
module.exports = {
entry: {
main: './src/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'web',
devtool: 'source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [
{
loader: "html-loader",
//options: { minimize: true }
}
]
},
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/html/index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
为了检测CSS简化插件是否工作,启动开发环境,在web的开发工具下,你会发现div的css中的
图片的链接为url;然而,启动生产环境,在web的开发工具下,div的css中的图片链接
为一大串字符(内容可能会变):
background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/4gxYSUNDX1BST0ZJTEUAAQEA…KAEYUAJigBrqAM0ARYGPwpXERSqOMcZxTAqyD5Se4oAoTE9M0CuUZuuM0AtSuSc9alsD//2Q==);