This paper optimizes the code of production environment from three aspects: code compression, code separation and style separation. These are the simplest configurations, but if they are implemented in a project, more configurations will need to be added depending on the project.
preface
This article is about how to compress the code in the production environment. If you are not familiar with Webpack, you can take a look at my last article: Build a Webpack development environment configuration from scratch.
This article project code location: source code address
Environment set up
The project structure
First write a project, initialize NPM, then install Webpack locally, then install WebPack-CLI (this tool is used to run WebPack on the command line) :
$ mkdir webpack-prod-demo
$ cd webpack-prod-demo
$ npm init -y
$ npm install webpack webpack-cli --save-dev
Copy the code
project
webpack-prod-demo
|- package.json
|- /public
|- index.html
|- /src
|- index.js
|- index.css
Copy the code
pubic/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack production environment configuration</title>
</head>
<body>
</body>
</html>
Copy the code
index.js
import './index.css';
function component() {
var element = document.createElement('div');
element.innerHTML = 'Hello World';
return element;
}
document.body.appendChild(component());
Copy the code
index.css
div {
color: blue;
text-align: center;
}
Copy the code
package.json
{
"name": "webpack-prod-demo"."version": "1.0.0"."description": ""."private": true."scripts": {
"test": "echo \"Error: no test specified\" && exit 1"."build": "webpack --config webpack.config.js"
},
"keywords": []."author": ""."license": "ISC"
}
Copy the code
Configure the webpack.config.js file
Create the webpack.config.js file in the root directory and perform basic configuration
Installing a plug-in
# installed Babel - loader
$ npm install babel-core babel-loader@7 --save-dev
Install the Babel presets
$ npm install babel-preset-env babel-preset-stage-0 --save-dev
Install Babel plugins
$ npm install babel-plugin-transform-class-properties babel-plugin-transform-runtime babel-runtime --save-dev
Install the rest of the required loader
$ npm install css-loader style-loader file-loader csv-loader xml-loader html-loader markdown-loader --save-dev
Install the WebPack plugin
$ npm install clean-webpack-plugin html-webpack-plugin friendly-errors-webpack-plugin --save-dev
Copy the code
Configuration webpack. Config. Js:
webpack.config.js
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
module.exports = {
mode: 'development'.devtool: 'hidden-source-map'.entry: './src/index.js'.output: {
filename: '[name]-[hash:8].js'.path: path.resolve(__dirname, 'dist')},plugins: [
new HTMLWebpackPlugin({
// The title of the HTML document to be generated
title: 'Webpack Production Environment Configuration '.// Webpack generates the template path
template: './public/index.html'
}),
New CleanWebpackPlugin(Paths [, {options}])
new CleanWebpackPlugin(['dist']),
// Make a friendly prompt at the command line
new FriendlyErrorsWebpackPlugin()
],
module: {
rules: [{test: /\.js/.include: path.resolve(__dirname, 'src'),
loader: 'babel-loader? cacheDirectory'
},
/ / CSS
{
test: /\.css$/.include: path.resolve(__dirname, 'src'),
use: [
'style-loader'.// You can also add some configuration to the loader
{
loader: 'css-loader'.options: {
/ / open sourceMop
sourceMap: true}}},// Parse image resources
{
test: /\.(png|svg|jpg|gif)$/.use: [
'file-loader']},// Parse the font
{
test: /\.(woff|woff2|eot|ttf|otf)$/.use: [
'file-loader']},// Parse data resources
{
test: /\.(csv|tsv)$/.use: [
'csv-loader']},// Parse data resources
{
test: /\.xml$/.use: [
'xml-loader']},// Parse the MakeDown file
{
test: /\.md$/.use: [
"html-loader"."markdown-loader"}]}}Copy the code
Create the.babelrc file in the project root directory
.babelrc
{
"presets": ["env"."stage-0"]."plugins": [
"transform-runtime"."transform-class-properties"]}Copy the code
Run the project after the basic configuration is complete
Run the command from the command line:
$ npm run build
Copy the code
At this time, open the HTML file under the dist folder in the browser, and the Blue Hello World is displayed on the page
Dist file size:
Set the mode toproduction
webpack.config.js
. module.exports = {mode: 'production'. }Copy the code
Run the project after setting it up for production
Run the command from the command line:
$ npm run build
Copy the code
At this point, open the HTML file under the dist folder in the browser, and the Blue Hello World can still be displayed on the page
Dist file size:
The focus of this article: optimizing packaging
Install the required plug-ins:
Install plugins that compress JS and CSS code
$ npm install uglifyjs-webpack-plugin optimize-css-assets-webpack-plugin --save-dev
Install plugins that extract CSS
$ npm install mini-css-extract-plugin --save-dev
Copy the code
Uglifyjs-webpack-plugin and optimize- CSS-assets-webpack-plugin
webpack.config.js
. ;const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = { ... .optimization: {
// Package compressed js/ CSS files
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
// UglifyJs deletes unused code without warning
warnings: false.// Delete all 'console' statements, compatible with Internet Explorer
drop_console: true.// Inline variables that are defined but used only once
collapse_vars: true.// Extract static values that occur multiple times but are not defined as variables to reference
reduce_vars: true,},output: {
// Most compact output
beautify: false.// Delete all comments
comments: false,}}}),new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
safe: true}}]}}Copy the code
Uglifyjs-webpack-plugin Please refer to the plugin documentation for more configurations.
Optimize – CSS -assets-webpack-plugin See the plugin documentation for more details.
The mini – CSS – extract – the use of the plugin
Note: MiniCssExtractPlugin. Loader used with style – loader problem may come up. So I’m going to remove the style-loader.
webpack.config.js
. ;const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
...
plugins: [
...,
// Extract the CSS file
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css'.chunkFilename: '[name].[contenthash:8].chunk.css'})].module: [
rules: [
...,
/ / CSS
{
test: /\.css$/.include: path.resolve(__dirname, 'src'),
use: [{loader: MiniCssExtractPlugin.loader
},
// You can also add some configuration to the loader
{
loader: 'css-loader'.options: {
/ / open sourceMop
sourceMap: true}}]},... ] ]}Copy the code
For more configuration, please refer to the mini-CSS-extract-Plugin documentation.
The chunk split
webpack.config.js
. ;module.exports = { ... .optimization: {
// Package compressed js/ CSS filesminimizer: [ ... ] .splitChunks: {
chunks: 'all'}}}Copy the code
For details about splitChunks configuration, see the official documentation.
To distinguish the environment
When developing web pages, there are usually multiple operating environments, such as:
- An environment that facilitates development and debugging during development
- Publish online to the user’s operating environment
In order to reuse the code as much as possible, we need to have a mechanism to differentiate the environment in the source code depending on the environment in which the target code is to run. Environments can be differentiated using the DefinePlugin plugin built into Webpack.
The reason for environment differentiation: Many third-party libraries have also been optimized for environment differentiation
- Development environment: contains type checking, HTML element checking, and other warning log code for developers
- Online environment: Removed all developer-specific code, leaving only the parts that make React work to optimize size and performance
Note: NODE_ENV and ‘production’ values are community conventions and are often used to distinguish between development and online environments.
Configuration:
webpack.config.js
. module.exports = { ... .plugins: [...// Distinguish the environment
new webpack.DefinePlugin({
// Define the NODE_ENV environment variable as production
'process.env': {
NODE_ENV: JSON.stringify('production'}})],... }Copy the code
Run the project after configuration optimization
Run the command from the command line:
$ npm run build
Copy the code
At this point, open the HTML file under the dist folder in the browser, and the Blue Hello World can still be displayed normally on the page
Dist file size:
The final code of the webpack.config.js file
The rest of the files are basically unmodified. Post the webpack.config.js code here
webpack.config.js
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production'.devtool: 'hidden-source-map'.entry: './src/index.js'.output: {
filename: '[name]-[hash:8].js'.path: path.resolve(__dirname, 'dist')},plugins: [
new HTMLWebpackPlugin({
// The title of the HTML document to be generated
title: 'Webpack Development Environment Configuration '.// Webpack generates the template path
template: './public/index.html'
}),
New CleanWebpackPlugin(Paths [, {options}])
new CleanWebpackPlugin(['dist']),
// Make a friendly prompt at the command line
new FriendlyErrorsWebpackPlugin(),
// Extract the CSS file
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css'.chunkFilename: '[name].[contenthash:8].chunk.css'
}),
// Distinguish the environment
new webpack.DefinePlugin({
// Define the NODE_ENV environment variable as production
'process.env': {
NODE_ENV: JSON.stringify('production')}})],module: {
rules: [{test: /\.js/.include: path.resolve(__dirname, 'src'),
loader: 'babel-loader? cacheDirectory'
},
/ / CSS
{
test: /\.css$/.include: path.resolve(__dirname, 'src'),
use: [{loader: MiniCssExtractPlugin.loader
},
// You can also add some configuration to the loader
{
loader: 'css-loader'.options: {
/ / open sourceMop
sourceMap: true}}},// Parse image resources
{
test: /\.(png|svg|jpg|gif)$/.use: [
'file-loader']},// Parse the font
{
test: /\.(woff|woff2|eot|ttf|otf)$/.use: [
'file-loader']},// Parse data resources
{
test: /\.(csv|tsv)$/.use: [
'csv-loader']},// Parse data resources
{
test: /\.xml$/.use: [
'xml-loader']},// Parse the MakeDown file
{
test: /\.md$/.use: [
"html-loader"."markdown-loader"]]}},optimization: {
// Package compressed js/ CSS files
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
// UglifyJs deletes unused code without warning
warnings: false.// Delete all 'console' statements, compatible with Internet Explorer
drop_console: true.// Inline variables that are defined but used only once
collapse_vars: true.// Extract static values that occur multiple times but are not defined as variables to reference
reduce_vars: true,},output: {
// Most compact output
beautify: false.// Delete all comments
comments: false,}}}),new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
safe: true}})].splitChunks: {
chunks: 'all'}}}Copy the code
contrast
Through the comparison of three packages, it can be seen that:
- After the first common configuration is packed, the package size is 48.1K
- The package size is 39.0K after it is set to the production environment for the second time
- The package is optimized for the third time and the package size is 1.46K
At present, this project is a JS file, the amount of code is very small, but you can still see the effect of optimization. If the project is larger, the optimization effect will be more obvious. Of course, more configuration may be required.
Program source code
The source address
conclusion
This article is just a simple optimization for code packaging in production, but more configuration may be required as the project goes live. In fact, no matter how many tutorials, in fact, the configuration can not necessarily meet their own requirements. In the development process, you still need to configure according to your requirements.
In fact, learning Webpack is not difficult, according to the official website instructions and guidelines, in fact, basic can use. The difficulty is the configuration of various Loaders and plugins themselves. All of these need to be researched in depth on the Loader and Plugin websites. So if you want to do a better webPack configuration, you still need to pay more attention to the emergence of the latest technology, and collect useful plug-ins and configurations. Every little makes a little bit of a difference, and over time a better project scaffolding can be built (which is currently my goal).