Lin Nerdy’s Road to Webpack – How to Build
preface
You wish the world, I wish you no bugs. Hello everyone! I’m Lin Dull!
What? ! You still want nerdy to come out and talk to you about Webpack? ! Boy, your idea is very dangerous β.
Impossible, the next time you want to see “her” may have to wait until the dull 5000 fans π. There’s no way I’ll ever dress up again π π before that.
So please wake up, the cute girl you see is a handsome boy! This handsome guy he’s got you! Of course, I don’t call myself handsome boy in real life, because I live in Guangdong, so they usually call me Liangzai.
In addition, I updated the github address of the textbook case of “Lin Dull’s Webpack Road Series”. Oh, the previous one was too messy and I deleted it. Now all the textbook cases are the same project, but separate cases can be downloaded in different branches, and all cases are in the trunk. Read README on Github for details. (github.com/LinDaiDai/w…).
Lin Dull to you launched a multi-person learning Webpack
Please select: βοΈ accept βοΈ reject
Webpack series introduction
This series documents my learning experience on Webpack. If you want to master Webpack as WELL as I do, I think it will be helpful to you, because the textbook is explained as a Webpack student, and the case demo is very detailed, involving:
- Based on article
- Construction Methods (This chapter)
- Optimize the article
- Loader article
- Configuration article
I suggest mark take some time to read it first.
(In fact, this series was written a long time ago, has not been sent out, at that time also wrote a long list of preface can move me, want to read nonsense can click here: GitHub address, but now let’s officially start learning)
All articles are webpack version number ^4.41.5, Webpack-CLI version number ^3.3.10.
In WebPack 3, WebPack itself and its CLI were in the same package, but in version 4, the two were separated, again to allow us to manage them better.
By reading this article you can learn:
- webpack –watch
- Webpack dev – server tools
- Webpack-dev-middle tool, and build local Web server with Express
- Webpack-merge builds different environments
- Basic use of process.env.node_env
- The webpack.defineplugin plugin specifies NODE_ENV
Several development tools
Running the NPM Run build manually becomes cumbersome every time the code is compiled.
Have you ever used scaffolding tools like VUe-CLI to create a local Web server each time you run the NPM run start command and open a port page like localhost:8080? There are also hot updates and other functions.
In fact, the implementation of these functions are vue-CLI internal use of Webpack.
Webpack has several different options to help you automatically compile your code after it changes.
(Section 1 teaching material caseLinDaidai/webpack-example/tree/webpack-serverβ οΈ : Read the README instructions carefully.)
Webpack’s Watch Mode
In observer mode, just configure a script command in package.json:
"scripts": {
"watch": "webpack --watch"
}
Copy the code
After using the NPM run watch command, you see the compilation process, but instead of exiting the command line, you monitor the files in real time.
For example, after you modify the local code and save it, it will compile again, without us to manually execute the compilation instructions, the disadvantage is that you need to manually refresh the page to see the changes.
(– Watch can also be shortened to -w)
webpack-dev-server
Using Webpack-dev-server gives you a simple Web server that listens for changes to files and automatically compiles them, as well as automatically refreshes the page. Better than observer mode.
Use steps:
-
$NPM I –save-dev webpack-dev-server
-
Add script command: “start”: “webpack-dev-server –open”
Effect of using this command:
Instead of generating the dist folder, a local Web server localhost:8080 is started
Every time the native code is changed, it is automatically recompiled and the page is refreshed
Other configuration items:
Webpack-dev-server also has many configuration items that can be configured in webpack.config.js
You only need to configure it in devServer, for example:
module.exports = {
devServer: {
contentBase: './dist'.// Tell the server where to supply the content
host: '0.0.0.0'.// The default is localhost
port: 8000.// Port number, default is 8080
open: true.// Whether to open the browser automatically
hot: true.// Enable webPack's module hot replace feature
hotOnly: true // Do not hot update when compilation fails}}Copy the code
If you use this feature, you’ll notice that it looks a bit like vue-CLI.
More information about devServer configuration can be found here: Server in Development.
webpack-dev-middleware
The basic use
Webpack-dev-middleware is a wrapper that can pass Webpack-processed files to a server.
Webpack-dev-server can start a local Web server because it is used internally, but it can also be used as a package on its own.
Here I will explain with the official case.
Use Webpack-dev-Middleware with Express Server to introduce its functionality.
(Express is a stripped-down Node.js framework that is easy to use if you haven’t used it before.)
Let’s start with my requirements. I want to implement this function:
- To configure a
script
The command allows it to run a localweb
The server (i.elocalhost: 3000
To view the page) - Native code can be recompiled with each change
- But the page does not refresh automatically
- Dependencies required for installation:
$ npm i --save-dev webpack-dev-middleware express
Copy the code
- Create a server.js file in the root directory of the project to write the local service:
// server.js
const express = require('express')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const app = express()
const config = require('./webpack.config')
const compiler = webpack(config)
// Pass the webPack processed file to a server
app.use(webpackDevMiddleware(compiler))
app.listen(3000.function() {
console.log('Example app listening on port 3000! \n');
})
Copy the code
- Configure the directive to run server.js in package.json:
{
"scripts": {
"server": "node server.js"}}Copy the code
PublicPath configuration items
While studying here, I also learned about the publicPath property of output in webpack.config.js.
I didn’t make much sense when I started looking at output.outputPath.
I gave it a try with webpack-dev-Middleware.
First, modify the webpack.config.js configuration:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin') module.exports = { entry: { app: './ SRC /index.js', print: './ SRC /print.js'}, devtool: 'inline-source-map', // Only development environment error trace plugins: [ new CleanWebpackPlugin({ cleanAfterEveryBuildPatterns: ['dist'] }), new HtmlWebpackPlugin({ title: 'Webpack Output2', filename: 'index.html', template: 'src/index.html' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'),+ publicPath: '/assets/'}}Copy the code
Then modify server.js:
// server.js const express = require('express') const webpack = require('webpack') const webpackDevMiddleware = require('webpack-dev-middleware') const app = express() const config = require('./webpack.config') const compiler = Webpack (config) // Pass the Webpack processed file to a server app.use(webpackDevMiddleware(Compiler){+,
+ publicPath: config.output.publicPath
+})) app.listen(3000, function() { console.log('Example app listening on port 3000! \n'); })Copy the code
NPM run server (localhost:3000)
Cannot GET /
Copy the code
You need to open localhost:3000/assets/ to see the correct page.
And if there are references to resources in the project, they are automatically prefixed with publicPath:
PNG => Change to /assets/icon.pngCopy the code
This option specifies the public URL for this output directory that is referenced in the browser.
Note β οΈ :
If output.publicPath and Webpack-dev-middleware’s publicPath are not configured, the default is “”, with the root as the configuration item.
If output.publicPath is configured, publicPath in Webpack-dev-middleware needs to be as well.
Second, the construction of different environments
The build goals for development and production environments are very different.
- In a development environment, you might have the ability to live reloading, hot Module replacement, and so on
- In the production environment, we are focusing more on smaller bundles, lighter source maps, more optimized resources, etc.
So to follow logical separation, we can write separate WebPack configurations for each environment.
Although we want to write separate configurations, there must be some common configuration items that we can extract and write different configurations in different files.
(Section 2 textbook caseLinDaidai/webpack-example/webpak-mergeβ οΈ : Read the README instructions carefully.)
webpack-merge
Finally, to merge these configuration items together, we need to use the Webpack-Merge tool.
First install this tool:
$ npm i --save-dev webpack-merge
Copy the code
Then let’s take apart the original webpack.config.js and write it into three different webPack configuration files:
webpack-demo
|- package.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
|- /dist
|- /src
|- index.js
|- math.js
|- /node_modules
Copy the code
webpack.common.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
entry: './src/index.js'.output: {
filename: '[name].bundle.js'.path: path.resolve(__dirname, 'dist')},plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'webpack bundle'}})]Copy the code
webpack.dev.js:
const merge = require('webpack-merge')
const commonConfig = require('./webpack.common')
module.exports = merge(commonConfig, {
devtool: 'inline-source-map'.// Error tracing
devServer: { // Set the file that webpack-dev-server listens to
contentBase: './dist'}})Copy the code
webpack.prod.js:
const merge = require('webpack-merge')
const commonConfig = require('./webpack.common')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
module.exports = merge(commonConfig, {
plugins: [
new UglifyJSPlugin() // Compress the output]})Copy the code
As you can see, webpack-merge combines the configuration of multiple Webpacks into one.
Now let’s configure the package.json script command again:
package.json:
{
"name": "webpack-bundle"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js"."build": "webpack --config webpack.prod.js"
},
"keywords": []."author": ""."license": "ISC"."devDependencies": {
"clean-webpack-plugin": "^ 3.0.0"."html-webpack-plugin": "^ 3.2.0"."uglifyjs-webpack-plugin": "^ 2.2.0." "."webpack": "^ 4.41.5"."webpack-cli": "^ 3.3.10"."webpack-dev-server": "^ 3.10.3"."webpack-merge": "^ 4.2.2." "}}Copy the code
- perform
npm run start
For the development environment, it opens automaticallylocalhost:8080
Page and automatic reload function - perform
npm run build
For production environment, will be packaged generationdist
Folder, andbundle
In thejs
Is the compressed code.
process.env.NODE_ENV
Basic usage
The main purpose of process.env.node_env is to help us determine whether it is a development environment or a production environment.
Technically, NODE_ENV is a system environment variable exposed by Node.js to execute scripts.
- You can do it at any
src
Reference to it in the native code of:
// print.js
export function print() {
console.log(process.env.NODE_ENV) // development ζθ
prodution
}
Copy the code
- But you are in
webpack.config.js
You can’t get it in. Print it outundefined
. So code like the following isIt doesn’t work out as expected:
process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'
Copy the code
Webpack DefinePlugin plug-ins
As mentioned earlier, we can’t get the value of process.env.node_env in webpack.config.js, but we can use the DefinePlugin built into Webpack to modify this variable.
For example, my configuration in webpack.prod.js:
+ const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const commonConfig = require('./webpack.common.js');
module.exports = merge(commonConfig, {
devtool: 'source-map',
plugins: [
new UglifyJSPlugin({
sourceMap: true
-})
+}).
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify('production')
+})]});Copy the code
Process.env.node_env was modified using the webpack.defineplugin () method.
You can set it to json.stringify (‘production’) or you can set it to:
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': `"production"`}})Copy the code
Command line configuration mode mode
In addition to using the webpack.defineplugin plugin to modify the schema of an environment variable, you can also modify it on the command line:
Webpack --mode=production or webpack --mode=developmentCopy the code
–mode is used to set the mode of the environment variable, and the value of process.env.node_env obtained from the local code is the value of mode.
But if you also set it on the command line--mode
, used againwebpac.definePlugin
Plugins, which have a higher priority.
The command line passes environment variables
If we set some variable values on the command line with –env, they will be accessible in our webpack.config.js configuration.
In webpack command line configuration, by setting--env
This allows you to pass in as many environment variables as you need
For example, if I create a new command line:
{
"scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js",
"build": "webpack --config webpack.prod.js",
+ "local": "webpack --env.custom=local --env.production --progress --config webpack.local.js"}}Copy the code
Break it down:
--env.custom=local
Set a custom property in the environment variablecustom
, its value islocal
--env.production
Set up theenv.production == true
(where theenv
Does not affectprocess.env
)--progress
Prints a percentage value for compilation progress--config webpack.local.js
δ»₯webpack.local.js
Perform a WebPack build on the content in
At the same time I create a wepack.local.js in the project root directory:
const commonConfig = require('./webpack.common')
const merge = require('webpack-merge')
module.exports = env= > {
console.log('custom: ', env.custom) // 'local'
console.log('Production: ', env.production) // true
return merge(commonConfig, {})
}
Copy the code
You can see that it differs from the generic webpack.config.js in that it exports a function that accesses env environment variables.
This allows us to retrieve the variable set on the command line.
The command line passes the environment variable to determine NODE_ENV
NODE_ENV: process.env.node_env: process.env.node_env: process.env.node_env: process.env.node_env: process.env.node_env
process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'
Copy the code
But now we pass in a variable called NODE_ENV on the command line, which can be distinguished in webpack.config.js.
Let’s create a configuration file called webpack.bine.js in the root directory:
webpack.combine.js:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = env= > {
return {
entry: './src/index.js'.output: {
filename: env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'.path: path.resolve(__dirname, 'dist')},plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'Merged into the same Webpack configuration'}}})]Copy the code
We can see ouput. Filename, which can be determined by NODE_ENV.
So I need to pass the parameters in package.json:
{" name ":" webpack - bundle ", "version" : "1.0.0", "description" : ""," main ":" index. Js ", "scripts" : {" test ": "echo \"Error: no test specified\" && exit 1", "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js", "local": "webpack --env.custom=local --env.production=false --mode=development --progress --config webpack.local.js",+ "combine-dev": "webpack --env.NODE_ENV=development --config webpack.combine.js",
+ "combine-prod": "webpack --env.NODE_ENV=production --config webpack.combine.js"}, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "clean-webpack-plugin": "^ 3.0.0 HTML - webpack -", "plugins" : "^ 3.2.0", "lodash" : "^ 4.17.15", "uglifyjs - webpack - plugin" : "^ 2.2.0", "webpack" : "^ 4.41.5 webpack -", "cli" : "^ 3.3.10", "webpack - dev - server" : "^ 3.10.3", "webpack - merge" : "^ 4.2.2"}}Copy the code
Now execute the combine-dev and combine-prod separately, and you can see the different effects of the generated bundle.
The js file generated by combining-dev is main.bundle.js
Combine to prod the generated js file is the main a79eb0c94212b905d48b. Bundle. Js
But it is important to note that env.node_env is not process.env.node_env, so it does not change process.env.
That is, no matter how you generate the page, the process. Env.node_env that you get in the page is still production.
Section 2 Summary
- Can be installed
webpack-merge
Tools help us combine multiple configuration files into one - in
webpack.config.js
Environment variables cannot be obtainedprocess
- Can be achieved by
webpack.DefinePlugin
Plug-ins help us modifyprocess.env
The value of the - You can also use the command line
CLI
In the--mode
To modify the mode of an environment variable - if
webpack.config.js
The output is a function, which allows us to use it on the command line--env
Passing environment variables
Case address
Section 1: github.com/LinDaiDai/w…
Section two: github.com/LinDaiDai/w…
Note β οΈ : in fact, “Lin Dull’s Webpack Road series” all textbook cases are the same project, but different branches can download separate cases, the main branch is all cases. Read README on Github for details.
Refer to the article
Knowledge is priceless, support original.
Reference article:
- Webpack Chinese document
After the language
The guy who likes Lin Dull also hopes to follow Lin’s public account LinDaiDai or scan the following QR code πππ.
I will update some front-end knowledge content and my original article π from time to time
Your encouragement is the main motivation for my continuous creation π.
Related recommendations:
The most detailed BPMN.js textbook in the whole Web
If you don’t understand Babel, I’ll send you a mask.
“[Suggested stars] To come to 45 Promise interview questions a cool end (1.1W words carefully arranged)”
“[suggestion π] 40 more this interview questions sour cool continue (1.2W word by hand)”
“[why not three even] more simple than inheritance of JS inheritance – packaging (small test)”
γ Why not three times γ finish these 48 questions to thoroughly understand JS inheritance (1.7W words including hot finishing – back to nature)
Data type conversion from 206 console.log()