Writing in the front

Installing the Node Environment

Webpack depends on the Node environment. You must ensure that Node is installed before WebPack is installed

NPM init Initialization

I’m going to manually create a new directory like testWebpack here and I’m going to do NPM init in testWebPack.

Package. json is the node package management file. If the current project needs to use node related packages separately, it should have package.json. This allows others to download the packages in package.json through NPM install when they get the project.

Install webpack

When we use Webpack 4+, we also need to install webpack-CLI, because webpack commands are in webpack-CLI.

// (install the specified version, do not specify the default install latest)
npm install webpack@4.411. --save-dev

npm install webpack-cli	--save-dev

// If the version number is displayed, webPack is successfully installed
webpack -v	
Copy the code

Pay attention to the point

All packages installed in package.json need to be removed with the ^ in front of the package version number. Otherwise, the package will be automatically updated, causing some functions to conflict with other packages or become unavailable

1. The webpack concept

Webpack: is a module packaging tool, the various formats of the project files as modules for unified packaging and compilation

2. The initial experience of Webpack

2.1 WebPack code in two modes

Manually create a SRC directory in the testWebpack directory and create index.js under SRC

// testwebpack/src/index.js
console.log('hello webapck');
Copy the code

Use the webpack command to pack webpack. / SRC /index.js -o./dist/bundle.js

Note the yellow warning in the image above. Set mode to dev or prod. If not set to prod, the default is prod.

Look at the bundled bundle.js (found to be compressed because prod is not set by default); You can Run this Code directly using the Run Code plug-in


To create the webpack.config.js configuration file in the testWebpack directory, take a look at the bundel.js file in dev mode

// testwebpack/webpack.config.js

module.exports = {
  mode: 'development' // Specify development mode as development
}
Copy the code

Js -o./dist/bundle.js: bundel.js: webpack. / SRC /index.js -o./dist/bundle.js

2.2 Simple package File Parsing in Dev Mode

Create a new a.js under SRC

// src/a.js
module.exports = 'I am a. s'

// src/index.js
let aa = require('./a.js')
console.log(aa);
console.log('hello webapck');
Copy the code

/ SRC /index.js -o./dist/bundle.js: webpack. / SRC /index.js -o./dist/bundle.js

Function point 1: One of the great features of WebPack from this parse file is that it takes the current file index.js as an entry point, looks up all dependencies, and prints them; This is equivalent to implementing require’s functionality inside Webpack and organizing dependencies

Function Point 2: Webpack starts with the import file module and organizes the other modules that it depends on, which eventually outputs as the configuration export file bundle.js. In bundle.js, it is a self-called anonymous function whose parameter is an object, each item in the object is a module, and each item’s key is the module name. Value is a function.

Module loading process analysis

2.3 Webpack Command Mapping

Do you find that we run webpack. / SRC /index.js -o./dist/bundle.js on the command line every time we pack? The answer is yes, in the package.json script command configuration


Benefits of command mapping:

If the command is too long, you can use this configuration. The commands run on the terminal are global commands. The command configured in the script script will be found locally (node/moudles) first, and will be used globally if it is not found.

How to use local commands without script configuration? /node_modules/webpack XXXXX./node_modules/webpack XXXXX

// Before mapping, use:
webpack ./src/main.js -o ./dist/bundle.js

// Map the webpack command to the package.json script; NPM run build == webpack
"scripts": {
    "build": "webpack"
},
npm run build ./src/main.js -o ./dist/bundle.js
// Configure the compiled file and packaged output file to the input and output, followed by 'NPM run build'
npm run build
Copy the code

3. Webpack basic configuration series

Note that the default webpack configuration file name is webpack.config.js

The main module configuration items of Webpack are:

  • Entry configuration/exit configuration
  • Loader configuration
  • Plugin Plugin configuration
  • Mode mode configuration (see webpack initial experience)

3.1 Entrance Configuration

Instead of specifying a separate entry each time, you can configure it in webpack.config.js

// webpack.config.js
const path = require('path')

module.exports = {
  mode: 'development'.// Specify dev mode
  entry: './src/index.js'.// Specify the entry file
  output: {
    // Note that this path must be an absolute path
    path: path.resolve(__dirname, 'dist'),  // Add the dist directory under the current directory and place the output in the file specified by filename
    filename: 'bundle.js'}}Copy the code

Add “build”: “webpack” to the package.json script so that it can be packaged and compiled from the command line using NPM run build

// package.json
"scripts": {
    "build": "webpack"
  },
Copy the code

The following figure shows the result of NPM run build

Note: here only lists the simple configuration of import file and export, and there are many specific configuration methods, such as string mode, object mode, etc. For details, please refer to the official website

3.2 loader configuration

By default, WebPack can only recognize and process JS files. For images, CSS, ES6, typescript, Vue, JSX and other advanced syntaxes, loader needs to convert them to recognized low-level syntaxes

3.2.1 CSS – loader&style – loader

Css-loader handles @import and URL (), just as JS interprets import/require()

Style-loader main functions: The CSS module files generated after the CSS -loader parsing are imported into the head tag of the generated template index.html file in style mode. It is likely to be overwritten by the styles that are wrapped and inserted at the bottom of the head tag, so style-loader provides options to change the insertion position.)

Less-loader transfers less files to CSS files

/ / installation
npm install css-loader --save-dev
npm install style-loader --save-dev
Copy the code
// webpack.config.js for configuration
module.exports = {
  mode: 'development'.entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),  // Add the dist directory under the current directory and place the output in the file specified by filename
    filename: 'bundle.[hash:8].js'          // bundle.[hash:8].js prevents caching, so every time you generate different bundle.js, you add hash, and the ':8' after it represents the number of hash digits
  },

  module: {
    rules: [{test: /\.css$/,
        use: [                            // Write style as an object, write csS-loader as a string
          {
            loader: 'style-loader'.options: {
              insertAt: 'top'             // Specify to insert the top of the haed tag, since the default is to insert it at the bottom of the head tag}},'css-loader']}]},}Copy the code
// Code tests csS-loader and style-loader
// a.css
body{
  background-color: red;
}

// index.css
@import './a.css';
body {
  background-color: pink;
}

// index.js
import './index.css'

let aa = require('./a.js')
console.log(aa);
console.log('hello webpack');

// require('./index.css') can also be imported
Copy the code


Note 1: If csS-Loader is not directly compiled and packaged, webapck will fail to recognize the error

Use: [‘style-loader’, ‘css-loader’, ‘less-loader’]

Note 3: Loader configuration can be written in multiple ways, such as strings and objects

Note 4: If only csS-loader is configured and style-loader is not configured, then the generated index.html will not contain the style file, in other words, the style is not introduced, because CSS-loader only resolves the @import and URL () path import problems in CSS

Note 5: Note that when there are only CSS-loader and style-loader, the dist directory does not generate the packaged CSS file separately, but directly introduces the style into the generated index. HTML in the way of style introduction. If there are many styles, it will be messy and difficult to manage the problem of style coverage. If CSS is to be exported as a module package file, like JS packaging, and eventually imported into index.html as an external link, then mini-CSS-extract-plugincss is required to be configured. (See the plugins section for details)

3.2.2 postcss – loader

By default, style attributes do not have browser-compatible prefixes such as the browser-compatible prefix -webkit-transform for transform

// Installation: Autoprefixer is a package that prefixes CSS properties with a browser, but requires postCSS-loader to convert them
npm install postcss-loader autoprefixer --save-dev
Copy the code
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  mode: 'development'.entry: './src/index.js'.module: {
    rules: [{test: /\.css$/,
        use: [                            
          MiniCssExtractPlugin.loader,
          'css-loader'.'postcss-loader'.// PostCSs-loader is prefixed with browser style compatibility before CSS -loader parsing]}]},}Copy the code

After configuration postcss – loader, how do you know which package postcss – loader can add prefix, so you need to create postcss in root directory. The config, js, is set in the configuration file, autoprefixer this package

// postcss.config.js
module.exports = {
  plugins: [
    require('autoprefixer')]};Copy the code

After configuring this, you also need to configure the conversion rules for different browsers or versions to be configured in package.json or to create.browserslistrc separately, which we will do in package.json

// package.json
  "browserslist": [
    "last 2 version"."1%" >."iOS >= 7"."Android 4.1" >."Firefox > 20"
  ]
Copy the code

View main.css after the NPM run build package

3.2.3 Babel – loader

Before babel-loader is configured, the following figure is shown:

/ / installation
// @babel/core: is the core module of Babel, which can call the transfor conversion method
// @babel/preset-env: Is Babel preset to turn ES6/7 into ES5 (wrapping the plugin into a package is preset)
npm install --save-dev babel-loader @babel/core @babel/preset-env
Copy the code

Arrow functions after ‘@babel/preset-env’ have been converted to ES5 functions

// webpack.config.js
{
  test: /\.js$/,
    use: {
      loader: 'babel-loader'.options: {
          presets: [
            '@babel/preset-env'		// @babel/preset-env is a Babel preset that can turn ES6/7 into ES5 (wrapping the plugin into a package is a preset)]}}}Copy the code


Class syntax is not supported by default.

// Follow the prompts to install plug-ins that support class attributes
npm install --save-dev @babel/plugin-proposal-class-properties
Copy the code
// webpack.config.js
      {
        test: /\.js$/,
        use: {
          // options are equivalent to babel-loader arguments; Presets are configured with packages that are programmed to act like a set of plugins; Plugins are plugins to babel-Loader that babel-Loader depends on.
          loader: 'babel-loader'.options: {
            presets: [
              '@babel/preset-env'           // @babel/preset-env is a Babel preset that can turn ES6/7 into ES5 (wrapping the plugin into a package is a preset)].plugins: [
              '@babel/plugin-proposal-class-properties']}},include: path.resolve(__dirname, 'src'),		// Applies only to js in the current directory SRC
        exclude: /node_modules/											// Exclude the node_modules directory
      }
Copy the code

After @babel/plugin-proposal-class-properties is configured, NPM run build package output is no longer error


Babel/Runtime and transform will be discussed later. I haven’t figured it out yet

Babel’s two modes OF API and syntax

zhuanlan.zhihu.com/p/147083132

Blog. Windstone. Cc/es6 / Babel / @…

3.2.4 eslint – loader

Eslint validates JS syntax

// Install ESLint for js syntax validation
npm install --save-dev eslint eslint-loader
Copy the code

/ / webpack. Config. Js configuration
rules: [{test: /\.js$/,
    use: {
      loader: 'eslint-loader'.options: {
        enforce: 'pre'                  // forces eslint-loader to execute before any other loader that handles JS. In normal cases, the Enforce of the Loader is normal. Enforce: POST indicates that the command is executed after normal}}}},Copy the code

3.2.5 file – loader

To import images directly into HTML, you can use htMl-withimg-loader (Google)

File-loader: generates an image internally to the dist directory by default and returns the name of the generated image.

In other words the import w3 from ‘. / the w3. PNG ‘is actually here to return to the w3 file – loader after processing, the output to the dist directory be7a673b229da4c8f9885f3398dab2d5. PNG

Before file-loader is used, an error message is displayed indicating that an imported image cannot be processed as a module

/ / installation
npm install file-loader --save-dev
// webpack.config.js
module: {
  rules: [{test: /\.(png|jpg|gif)$/,
      use: 'file-loader'}}Copy the code

After configuring file-loader, use NPM run build to package and compile, and then use NPM run dev. In the browser address bar localhost:8080, the running results are as follows: The pictures are packaged as modules and output to the dist directory folder. And it’s time-stamped

3.2.6 url – loader

Url-loader is usually configured directly instead of file-loader. Url-loader contains the file-loader function. Url-loader can be restricted. For example, base64 encoding is used when the image is smaller than k, otherwise file-loader is used to directly output the image.

/ / installation
npm install url-loader --save-dev
Copy the code
// webpack.config.js
rules: [{test: /\.(png|jpg|gif)$/,
    use: {
      loader: 'url-loader'.options: {
        // If the image is less than 200K, use base64 encoding to convert, otherwise use file-loader to generate real images; 1 * 1024 * 1024 is 1 m
        limit: 200 * 1024}}}]Copy the code

When the image size is smaller than the limit, base64 encoding is used, and no image file is output in dist directory

When the size of an image exceeds the limit, the file loader is used to package the image and output it to the dist directory

3.3 the plugin configuration

  • Plugin: Plugin is an extension of the existing Webpack, while loader is just a type conversion, equivalent to a converter; In addition to third-party plugins that require the import to be installed, Webpack also comes with built-in plugins that can be used in webpack.config.js using require imports

  • Procedure: 1. Install NPM first. 2. Configure it in webpack.config.js

3.3.1 HtmlWebpackPlugin

By default, you need to create index.html manually, package the js file on the command line, and print the bundle.js file. You also need to manually embed the bundle.js file in the form of scrpit tags in index.html. But all of this affects productivity. Are there plug-ins that automatically help us with this process? The answer is HtmlWebpackPlugin (still need developers create index under the SRC. HTML, HtmlWebpackPlugin automation is create under the SRC index. The HTML is copied to the dist, And embed the generated bundle.js in index.html under dist for the developer.)

/ / installation
npm install html-webpack-plugin --save-dev
Copy the code

Configuration:


// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development'.entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),  // Add the dist directory under the current directory and place the output in the file specified by filename
    filename: 'bundle.[hash:8].js'          // bundle.[hash:8].js prevents caching, so every time you generate different bundle.js, you add hash, and the ':8' after it represents the number of hash digits
  },

  // Array holds all webPack plugins
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// Specify the configuration template. The final template in Dist will be generated from the template configured here
      filename: 'index.html'.// The final template generated in configuration Dist is named index.html
      minify: {                       // Minify compresses the index.html HTML code because the default PROD mode JS code is also compressed
        removeAttributeQuotes: true.// Remove double quotes
        collapseWhitespace: true      // Display all in one line
      },
      hash: true.// Hash bundle.js (Note: the hash option configured via HtmlWebpackPlugin will only hash bundle.js embedded in dist index.html, but bundle.js in dist is not displayed with hash)}})],Copy the code

Note 1: The difference between the hash configured by the HtmlWebpackPlugin and the hash configured by output.filename

Note 2: As long as the file is not modified, the hash code generated each time is the same

3.3.2 rainfall distribution on 10-12 mini – CSS – extract – the plugin

The dist directory does not generate the packaged CSS file separately, but directly introduces the style into the generated index.html in the way of style. If there are many styles, it will be very messy and difficult to manage the problem of style coverage. If CSS is to be exported as a module package file, like JS packaging, and eventually imported into index.html as an external link, then mini-CSS-extract-plugincss is required to be configured.

/ / installation
npm install mini-css-extract-plugin --save-dev
Copy the code
/ / webpack. Config. Js configuration
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  mode: 'development'.entry: './src/index.js'.output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[hash:8].js'
  },
  module: {
    rules: [{test: /\.css$/,
        use: [
          / / {
          // loader: 'style-loader',
          // options: {
          // insertAt: 'top'
          / /}
          // },
          MiniCssExtractPlugin.loader,    // Place the following csS-loader file in the dist output directory as a separate main. CSS and import it into index.html as an external link
          'css-loader'] {},test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,    // Place the following csS-loader file in the dist output directory as a separate main. CSS and import it into index.html as an external link
          'css-loader'.'less-loader']]}},plugins: [
    new MiniCssExtractPlugin({
      filename: 'main.css'                // Specify that the final package generated in the dist directory style file name is main.css}})],Copy the code

Note above MiniCssExtractPlugin. Loader for CSS and less processed in the main file. The CSS file, if you want to separate, you can import MiniCssExtractPlugin2 againconst MiniCssExtractPlugin2 = require('mini-css-extract-plugin')

3.3.3 CleanWebpackPlugin

CleanWebpackPlugin can delete all the last output package files in dist directory before each build, so as to prevent the accumulation of package files in dist directory for multiple builds. The final effect is that only the newly generated package files are stored in dist directory

/ / installation
npm install clean-webpack-plugin --save-dev
Copy the code
// webpack.config.js
const { CleanWebpackPlugin } = require('clean-webpack-plugin')  // Notice the deconstruction here
module.exports = {
  mode: 'development'.// Array holds all webPack plugins
  plugins: [
    new CleanWebpackPlugin(),
  ],
}
Copy the code

We optimize – CSS – assets – webpack – the plugin

By defaultmode: 'production'Js files are compressed, but CSS is not

Optimize – CSS -assets-webpack-plugin However, once the developer configures this plug-in for CSS compression optimization, webpack’s compression of JS will be invalid by default. Therefore, the developer also needs to install uglifyjs-webpack-plugin to configure compression of JS

/ / installation
npm install --save-dev optimize-css-assets-webpack-plugin
npm install --save-dev uglifyjs-webpack-plugin
Copy the code
/ / webpack. Config. Js configuration
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  optimization: {                           / / optimization
    minimizer: [
      new OptimizeCssAssetsWebpackPlugin(), // Compress the CSS code
      new UglifyjsWebpackPlugin()           / / compression js code (before the default configuration OptimizeCssAssetsWebpackPlugin js compressed call this UglifyjsWebpackPlugin js compressed)]},mode: 'production'.// development | production
}
Copy the code

Note:

By default, in PROD mode, JS is compressed but CSS is not

Optimize – CSS-assets-webpack-plugin is only configured for CSS compression, js compression default will be invalid

If you manually configure optimized-csS-assets-webpack-plugin for CSS compression, then you must manually configure JS compression using uglifyjs-webpack-plugin


3.3.5 copy – webpack – the plugin

The files in SRC are packaged into the dist directory. That’s because the SRC directory has entry files. From entry files, dependencies are packaged together and exported to the dist directory. However, if you simply want to copy certain directories/files to the dist directory, such as a doc document folder, you can use the copy-webpack-plugin.

// Install 6.2.1, version 7 will have some problems
npm install copy-webpack-plugin@6.21. --save-dev

/ / webpack. Config. Js configuration
const CopyWebpackPlugin = require('copy-webpack-plugin')
plugins: [
  new CopyWebpackPlugin({           // copy specified directory or file to dist directory; The./ represents the dist directory
    patterns: [{from: 'doc'.to: './doc'}]}),],Copy the code

3.3.6 bannerPlugin

BannerPlugin can add a string of copyright notices to the content header of packaged output JS and CSS files. Is a built-in plug-in for WebPack

// webpack.config.js
const Webpack = require('webpack')
plugins: [
  new Webpack.BannerPlugin("make by isisxu in 2020~2021")   // The BannerPlugin plugin built into Webpack adds a string copyright notice to the header of the packaged output JS and CSS files].Copy the code

4. Perform other configurations

4.1 webpack – dev – server

By default, the js files we package that we want to run can only be accessed in the browser as file://xxxindex.html, and the index.html web page. However, if we want to access the domain name port of the server https://localhost:xxx, we can use the devServer that comes with Webapck.

Another notable feature of webpack-dev-server is that the pricing of the dist folder is stored on disk by default, which is still very slow even if it is accessed in a browser as file://xxxindex.html. But the devServer feature, in addition to starting a server locally, also places the generated files in memory instead of disk, so that every time a developer changes the contents of the files, they are automatically compiled and updated into memory immediately because the server is always up. Unlike when the server is not up, this compilation is finished and the next time you need to manually enter the compilation command on the command line.


NPM install –save-dev webpack-dev-server, then configure the command in script

"scripts": {
  "dev": "webpack-dev-server"
},
Copy the code

Next, configure devServer in webpack.config.js

module.exports = {
  devServer: {
    port: 3000.// Specify the port to start the server
    progress: true.// The packaging process displays a progress bar
    contentBase: './dist'.// Specify that the server is started in the./dist directory
    inline: true.// Refresh the page in real time
    open: true              // After starting the server, the server automatically opens the localhost address in the browser. If you do not set this parameter, you need to manually open the browser and enter localhost}}Copy the code

NPM run dev will not generate the dist folder, because the generated files are in memory, so you will not see the dist directory, access directly in memory.

4.2 Multi-Page Resource Application Classification

Output the image to the specified directory in dist. Configure the outputPath attribute of urL-loader. And the introduction of the response position to the image will automatically become image/be7a67…. png


Pack CSS to the specified directory in DIST and configure the filename property of MiniCssExtractPlugin:


Imagine that static resources such as images are generally placed on the CDN. If you want to add the CDN prefix to images, CSS, JS and so on in the output, how to operate? You can configure the publicPath attribute

If you want to prefix images with the CDN domain name, you only need to add publicPath to the image configuration of the URL-loader. Do not configure the output export


*** Multi-entry, multi-exit configuration: *** If chunks are not specified, the default generated HTML will bring all generated JS files to one side

// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode: 'development'.entry: {
    home: './src/index.js'.other: './src/other.js'
  },
  output: {
    // [name] : the name in square brackets represents the variable, i.e. the './ SRC /index.js' package home.js; / SRC /other.js' package output other.js
    filename: '[name].js'.path: path.resolve(__dirname, 'dist')},plugins: [
    new HtmlWebpackPlugin({
      template: './index.html'.// index.html is a manually created template
      filename: 'home.html'.// home.html is output from the index. HTML template to the dist directory, and home.html imports home.js
      chunks: ['home']							// Specify which js to introduce in home.html; If you want to introduce other.js in home.html, you can configure chunks:['home', 'other']
    }),
    new HtmlWebpackPlugin({
      template: './index.html'.filename: 'other.html'.chunks: ['other']]}})Copy the code

4.4 the source – the map

Js files generated in PROD mode have been compressed and packaged, so it is difficult to debug and locate the specific error location. You need source-map

If the file is not processed, the default error message is a packed and compressed file, and the error message is not obvious:

Click the error link to jump to:

4.4.1 source – the map

In addition to the compressed code, source-Map will also generate a separate source map file corresponding to it in the dist directory. After errors are made, click to directly locate the row and column in error

// webpack.config.js
devtool: 'source-map'
Copy the code

Note that index.js:23 means the error occurred at line 23, and the column is the red wavy line indicating the beginning of the column

4.4.2 eval – source – the map

Eval-source-map does not produce a separate mapping file in the dist directory, but can display the row and column that reported an error

4.4.2 being – the module – the source – the map

Cheap-module-source-map produces a separate mapping file, but does not produce columns;

4.4.4 being – the module – the eval – source – the map

Cheap -module-eval-source-map does not generate separate mapping files. In the dist directory, the generated mapping is integrated into the packaged file, and no columns are generated.


Summary: What looks like a lot of configuration items are just any combination of the keywords eval, source-map, cheap, module, and inline. Each of these five keywords represents a feature, and these four features can be combined in any way. They represent the following five characteristics (it’s a bit unclear to read the description separately, so don’t worry, read on) :

  • Eval: Wrap module code in eval
  • The source – the map: produce.mapfile
  • Cheap: Does not contain column information (explained in more detail below) nor the Sourcemap of the Loader
  • Module: contains loader sourcemap (e.g. JSX to JS, Babel sourcemap)
  • The inline:.mapEmbedded as DataURI and not generated separately.mapFiles (this configuration item is rare)

Source-map summary reference

4.5 watch usage

If you want to output packaged and compiled files to the dist directory after each package and compilation, and do not need to manually execute NPM run build each time, you can configure Watch to start real-time monitoring and automatic package and compilation. So what’s the difference between Watch real-time monitoring and Web-dev-serve? The difference is that web-dev-server does not output static files to the dist directory. Watch does

After configuring watch, when we execute NPM run build package compilation, we will not directly end and exit the command line, but stop to monitor in real time.

// webpack.config.js
module.exports = {
  watch: true.// Enable real-time monitoring
  watchOptions: {
    poll: 1000.// Does polling monitor ask me 1000 minor updates per second
    aggregateTimeout: 500.// Stop the input and save it for 500 milliseconds
    ignored: /node_modules/ // The file directory that does not need to be monitored}}Copy the code

4.6 resolve

Resolve configures how Webpack finds the files for the modules that depend on it, starting from the configured entry module. Webpack built-in

JavaScript modular syntax parsing features are found by default using the rules specified in the modular standard, but you can modify the default rules to suit your needs.

/ / webpack. Config. Js configuration
resolve: {alias: {// alias Configures the alias.
    components: './src/components/'.'react$': '/path/to/react.min.js'		// Indicates that import statements ending with react can be replaced}},// When you import Button from 'components/ Button ', the alias is replaced by import Button from './ SRC /components/ Button '.
Copy the code

There are third-party modules that provide bits of code for different environments. For example, two pieces of code using ES5 and ES6 are provided respectively. The locations of these two pieces of code are written in package.json file as follows:

{
  "jsnext:main": "es/index.js".// Code entry file using ES6 syntax
  "main": "lib/index.js" // Code entry file using ES5 syntax
}
Copy the code

Webpack decides which code to use first based on the configuration of mainFields; Webpack will go through the package.json file in the order of the array, using only the first one it finds.

If you want to use the ES6 code first, you can do this


mainFields: ['browser'.'main']	// mainFields default value

/ / webpack. Config. Js configuration
resolve: {mainFields: ['jsnext:main'.'browser'.'main']}Copy the code

If you want to match the vue suffix of index.vue, you can use extensions

// webpack.config.js
resolve: {extensions: ['.vue'.'.js'.'.json']}// require('./data'), data.vue, data.js, data.json, data.json
Copy the code

5. Cross-domain issues in Webpack

Cross-domain is when js from one domain requests another domain.

Protocol, domain name /IP, port; If one of them is different, it is considered to be cross-domain.


You can write server.js locally because webPack already relies on Express, so you don’t need to install Express, which is a Web framework for Node.

Run server.js directly from Node

// src/server.js
let express = require('express')
let app = express()

app.get('/user'.(req, res) = > {
  res.send("I'm the return message from the server hello")
})
app.listen(3000.'127.0.0.1')  // The IP address can be omitted, and the default listener is localhost
Copy the code

After the execution node server. Js, equivalent to start express provides a web server, and then directly in the browser to http://localhost:3000/api/user


What if the address requested by the client is not a server address? With devServer of Webpack as intermediate proxy, the request proxy of client is forwarded to server’s service. Talk is cheap, show you the code

// src/index.js
// Simulate test client
// Note that http://localhost:8080 is requested by default, but http://localhost:3000 is started in server.js, so it cannot be accessed across domains.
// To provide an idea, you can first ask the client to send the request to webPack devServe, devServer is http://localhost:8080 service, Then have devServer forward to the http://localhost:3000 service of server.js
let xhr = new XMLHttpRequest()
xhr.open('GET'.'/api/user'.true)
xhr.onload = () = > {
  console.log(xhr.response);
}
xhr.send()


// src/server.js 
let express = require('express')
let app = express()

app.get('/api/user'.(req, res) = > {
  res.send("I'm the return message from the server hello")
})
app.listen(3000.'127.0.0.1')  // The IP address can be omitted, and the default listener is localhost
Copy the code
// webpack.config.js
devServer: {
  proxy: {
    '/api': 'http://localhost:3000'   Port is not set. DevServer starts at 8080 by default. In this case, http://localhost:8080 domain names that start with/API will be proxy to http://localhost:3000 domain names}}Copy the code

The terminal node server.js starts the server provided by the Express framework, and then NPM run dev runs the Webpack project. The configuration devServer of WebPack will be started.

If directly to http://localhost:8080/api/user in the address bar at this time, the process is equivalent to not go index. The js’s request, but the address bar to simulate the client, a visit to the http://localhost:8080/api/user address, DevServe listening to, to forward it directly to http://localhost:3000/api/user, and returns the result

If you access localhost:8080 directly from the address bar, the procedure is equivalent to index.js — >devServer — >server.js


Can the path requested by the client be changed? After rewriting the path proxy, you only need to configure the proxy proxy

// webpack.config.js
devServer: {
  proxy: {
    '/api': {
      target: 'http://localhost:3000'.pathRewrite: { '/api': ' ' }           / / said client request http://localhost:8080/api/user, hit devServe proxy, match after match/API forwarded to the target under the specified domain, and the original path of/API replace empty, new agent address as follows: http://localhost:3000/user. The listener on the server is also /user}}}Copy the code

What if the front end wants to mock the data itself? You can configure it directly in devServer because devServer has Express built in, and devServer provides hook functions to write service coupon code.

// src/index.js
let xhr = new XMLHttpRequest()
xhr.open('GET'.'/user'.true)
xhr.onload = () = > {
  console.log(11111, xhr.response);
}
xhr.send()


// webpack.config.js
devServer: {
  before (app) {		// Built-in hook function provided by devServer, before is executed before devServer starts. The mock server returns JSON data
    app.get('/user'.(req, res) = > {
      res.json({ data: 'I'm data returned by the server.'}})})},Copy the code

Start devServe by executing NPM run dev and then accessing localhost:8080 in the address bar



Here’s the problem! I just wanted to know if you were scared? — > If you want to start webpack directly from server without devServer; And the Server and Webpack share a port (which requires the server and client to be together).

This is done with the middleware of Webpack-dev-Middleware. Go here, the basic use of Webpack master is almost the same, in fact, Webpack is a module

Just hand over the compilation results of the imported Webpack.config. js to middleware before Express starts the server

/ / installation
npm install webpack-dev-middleware --save-dev
Copy the code
// testwebpack/server.js // note that this is the root directory server.js
let express = require('express')
let webpack = require('webpack')			// Import webpack module
let middleware = require('webpack-dev-middleware')		// Import the middleware module

let app = express();
let config = require('./webpack.config.js')						// Before starting the Express server, run the
let compiler = webpack(config)

app.use(middleware(compiler))

app.get('/user'.(req, res) = > {
  res.send("I'm the return message from the server hello")
})

app.listen(3000)
Copy the code

CD Go to the root directory and run node server.js

At this point to http://localhost:3000/user is simulated client address bar; If you go directly to http://localhost:3000/, you will access the index.js package in the index.html package of webpack

Series of problems

Question: Why is the configuration file calledwebpack.config.js?

Question: If you don’t want to barkwebpack.config.jsCan you change it?

When the package command is executed, add –config to specify the configuration file name

NPM run build can also be configured using script, so that when running NPM run build directly, first go to node/moudels to search for webpack command, then use webpack command to execute, specify the my.webpack.js configuration file, The import and export files are read from this configuration file and packaged

// package.json
"scripts": {
  "build": "webpack --config my.webpack.js"
}
Copy the code

Question: Why do YOU need Base64 to transform images?

The Base64 encoding of images can encode an image data into a string, which can be used instead of the image address. Every image we see on a web page requires an HTTP request to download (hence the cSSSprites technology, but cSSSprites has its own limitations, which will be discussed below).

Yes, images are always requested to the server anyway, and it would be nice if images could be downloaded locally along with HTML instead of being requested to the server. Base64 solves this problem.

If the image is small enough and cannot be made into CS Sprites due to the particularity of its use, it has high reusability in the whole website and will not be updated basically

(Specific process analysis can refer to: Playing with pictures Base64 coding)

Q: Why does require sometimes add a path and sometimes not?

// This type of pathless module is found in node_modules
require('webpack')
// Add path to the file module, not in node_modules
require('./webpack.config.js')
Copy the code

Question: Why is there no cross-domain problem with the proxy configured?

Because cross-domain restrictions are the behavior of browsers, browsers do not allow scripts to access across domains; But for devServer as a server, the back-end service request request interface has no cross-domain constraints.