Webpack introduction

Webpack is a static module packaging tool for modern JavaScript applications. Is a front-end build tool.

Webpack has five core concepts

Entry

Entry: Indicates which file webPack starts packing as the Entry point, analyzing and building internal dependency diagrams.

Loader

Loader: Enables Webpack to handle non-JS files/JSON resources, such as style files, image files (Webpack only understands JS)

Plugins

Plugins: Can be used to perform a wider range of tasks. Plug-ins range from packaging optimization and compression to redefining variables in the environment.

Mode

Mode: Instructs Webpack to use the configuration of the corresponding Mode.

  • Development: Production mode, an environment in which code can be debugged locally
  • Production: The runtime environment that allows code to be optimized online.

Output

Output: Indicates where the Output of resource bundles packaged by Webpack goes and how to name them.

Simple WebPack packaging test

Package JS, JSON files

import data from './demo.json';
// Import non-JS, JSON resources, packaging error, so need to use loader to enable webpack to package non-JS, JSON resources.
// import "./index.css";
console.log("= = = = = = = = ="."I'm index.js file");
console.log(data)
​
// webpack ./src/index.js -o ./build/built.js --mode=development 
// Package js,json file will not report errors
Copy the code

Conclusion:

  1. Webpack can handle JS/JSON resources, not other resources.
  2. Both production and development environments can translate es6’s modular syntax into a syntax that browsers can recognize.
  3. The production environment compresses the packaged JS code.

Let WebPack support CSS packaging

The sequence of loaders in the use array is from right to left and from bottom to top

‘style-loader’, create style tag, insert js style resource, add it to head to take effect.

‘CSS-loader’, turns CSS files into commonJS modules and loads them into JS with style strings.

 // Process CSS files
{
  // All the matched files need to be converted by loader.
  test: /.css$/.// The loader to be used is executed from the back to the front
    use: [
      // Create a style tag and insert the js style resource into the head.
      'style-loader'.// Change the CSS file into a commonJS module and load the js file with the style string.
      'css-loader']},Copy the code

Let WebPack support sASS packaging

Sass: cannot find module sass: sass: cannot find module sass:

 // Process sass files
{
  test: /.scss$/,
    use: [
      'style-loader'.'css-loader'.'sass-loader']}Copy the code

Let WebPack support packaging HTML resources

Install the html-webpack-plugin. And it needs to be introduced to use it.

By default, an empty HTML file is created and the packaged JS file is imported.

If you want to specify an HTML template, you pass in the template attribute. Specifies the path to the template.

// Introduce HTML packaging plug-in
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})]Copy the code

Let WebPack support packaging image resources

In Webpackage 5+, the above method is obsolete, webpackage 5 uses the “resource module” instead of the above loader. The official explanation for “resource modules” is this.

Asset Module is a module type that allows you to use resource files (fonts, ICONS, etc.) without having to configure an additional loader.

  • Asset/Resource: Sends a separate file and exports the URL. This was previously implemented using file-loader.
  • Asset /inline: Exports a resource’s data URI. This was previously implemented using urL-loader.
  • Asset /source: Exports the source code of the resource. This was previously implemented using raw-loader.
  • Asset: Automatically selects between exporting a data URI and sending a separate file. Previously, the urL-loader was used and the resource volume limit was configured.

Visit juejin.cn/post/697033…

The way images in styles are handled

Problem: img images in HTML cannot be processed by default

/ / way
 {
   test: /.(jpe? g|png|svg|gif)/i,
     type: 'asset/resource',},2 / / way
  // This is the image resource introduced in the processing style
  {
    test: /.(png|gif|jpg|jpeg)/,
      use: [
        {
          loader: "url-loader".options: {
            // Advantages: reduce the number of requests (reduce server stress) // disadvantages: larger image size (slower file request)
            limit: 8 * 1024.// Specify the maximum size of the image to base64 format. It's less than that and it gets converted
            name: '[name].[hash:10].[ext]'.// Rename the file
            outputPath: 'static/img'.// The output position of the file
            esModule: false.// We need to close the esModule because it conflicts with commonJS modularity}}].type: 'javascript/auto'
  },
Copy the code

Handles images introduced in HTML

Its role is to process the IMG in HTML and hand it to urL-loader.

// This is to handle the image resources introduced in HTML
{
  test: /.html$/,
    loader: 'html-loader'
}
Copy the code

Make WebPack support for packaging other resources

file-loader

// Package other resources (other than HTML/JS/CSS resources)
{ // Exclude CSS /js/ HTML resources
  exclude: /.(css|js|html|sass|json|png|gif|jpg|jpeg)$/,
    loader: 'file-loader'.options: { name: '[hash:10].[ext]'}}Copy the code

But test yourself if you introduce font ICONS. Webpack then specifies the packaging, without the need to use file-loader.

Complete configuration in the development environment

const { resolve } = require("path")
// Introduce HTML packaging plug-in
const HtmlWebpackPlugin = require('html-webpack-plugin');
​
module.exports = {
  entry: "./src/js/index.js".output: {
    filename: 'built.js'.path: resolve(__dirname, 'build')},module: {
    rules: [
      // Process CSS files
      {
        // All the matched files need to be converted by loader.
        test: /.css$/.// The loader to be used is executed from the back to the front
        use: [
          // Create a style tag and insert the js style resource into the head.
          'style-loader'.// Change the CSS file into a commonJS module and load the js file with the style string.
          'css-loader']},// Process sass files
      {
        test: /.(scss|sass)$/,
        use: ['style-loader'.'css-loader'.'sass-loader'],},// Image processing method 1
      / / {
      // test: /.(jpe? g|png|svg|gif)/i,
      // type: 'asset/resource',
      // },
      // This is the second way to deal with the image resources introduced in styles
      {
        test: /.(png|gif|jpg|jpeg)/,
        use: [
          {
            loader: "url-loader".options: {
              limit: 8 * 1024.name: '[name].[hash:10].[ext]'.outputPath: 'static/imgs'.esModule: false,}}],type: 'javascript/auto'
      },
      // This is to handle the image resources introduced in HTML
      {
        test: /.html$/,
        loader: 'html-loader'
      },
      // Package other resources (other than HTML/JS/CSS resources)
      { 
        // Exclude the file resources processed above
        exclude: /.(css|js|html|sass|json|png|gif|jpg|jpeg)$/,
        loader: 'file-loader'.options: { name: '[hash:10].[ext]'.outputPath: "static/others"}}},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})].// The mode to use
  mode: 'development'.devServer: { // Project build path
    contentBase: resolve(__dirname, 'build'),
    // Start gzip compression
    compress: true./ / the port number
    port: 3000.// Automatically open the browser
    open: true}}Copy the code

Let WebPack pack CSS separately

Style-loader: it is used to create a style label in HTML, and then write the CSS in JS to the style, which makes the JS file very large, and may appear flash screen phenomenon, so it is necessary to extract the CSS file and pack it separately.

Mini-css-extract-plugin provides a loader to package CSS separately.

module: {
  rules: [
    / / deal with CSS
    {
      test: /.css$/,
      use: [
        // Package the CSS in js separately
        MiniCssExtractPlugin.loader,
        'css-loader']]}},plugins: [
  new MiniCssExtractPlugin({
    // Name the packaged file
    filename: 'static/built.css'})].Copy the code

Troubleshoot compatibility problems with the CSS

Postcss-loader, postCSs-PRESET -env needs to be installed.

npm install --save-dev postcss-loader postcss-preset-env
Copy the code

You need to configure compatibility between the development environment and production environment in package.json.

For details about browser compatibility, visit github.com/browserslis…

"browserslist": { "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], "production": [">0.2 ", "not dead", "not op_mini all"]}Copy the code

By default, WebPack handles CSS compatibility for production environments. If we want to work according to the development environment, we need to configure the environment variables in webpack.config.js

process.env.NODE_ENV = 'development';
Copy the code
module: {
    rules: [
      / / deal with CSS
      {
        test: /.css$/,
        use: [
          // Package the CSS in js separately
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader'.options: {
              postcssOptions: {
                // WebPack 4 configuration
                // ident: 'postcss',
                // plugins: () = [
                // require('postcss-preset-env')()
                // ]
                // WebPack 5 configuration
                plugins: [require('postcss-preset-env')()]}}}]}},Copy the code

Compressing CSS Files

Install the optimize- CSS – Assets -webpack-plugin. Then introduce and use it

// Compress the CSS file
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
plugins: [
  new OptimizeCssAssetsWebpackPlugin()
],
Copy the code

Let Webpack support js syntax checking

NPM install –save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import

Configure inspection rules in package.json

"eslintConfig": {
  "extends": "airbnb-base"."env": {
    "browser": true}}Copy the code

Configure the check in webpack.config.js

  module: {
    rules: [{// Webpack checks the JS syntax
        test: /.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader'.// When a file needs to be loaded with multiple loaders, specify which one to execute first.
        enforce: 'pre'.options: {
          // Automatically fixes esLint errors
          fix: true,},},],},Copy the code

Or via the eslint-webpack-plugin

// Check the js code
const EslintWebpackPlugin = require('eslint-webpack-plugin');
plugins: [
  new EslintWebpackPlugin(),
],
Copy the code

Deal with JS compatibility issues

NPM install –save-dev babel-loader @babel/ core@babel /preset-env core-js

If you don’t need all js compatibility: you don’t need to download and import the @babel/ Polyfill package.

module: {
  rules: [
    // Handle js compatibility
    {
      test: /.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader'.options: { 
        // Default: tell Babel what compatibility processing to do
        presets: [['@babel/preset-env', {
          // Load as needed
          useBuiltIns: 'usage'.// Specify the core-js version
          corejs: { version: 3 },
          // Specify which browser version is compatible
          targets: {
            chrome: '60'.firefox: '60'.ie: '9'.safari: '10'.edge: '17',},}]],},},},Copy the code

Compress JS, HTML files

Set the mode property to production directly. Indicates that in a production environment, it automatically compresses JS and HTML files.

Or specify compressed items in HTML

 plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// Compress the HTML code
      minify: {
        // Remove whitespace
        collapseWhitespace: true.// Remove comments
        removeComments: true}}),].Copy the code

Complete configuration in production environment

The same type of file is loaded by loader, and we need to figure out its priority. Prevent unnecessary errors. Js files need to be checked for code specification and JS compatibility. Code checking takes precedence over JS compatibility. So you need to load eslint-loader first and then load babel-loader. We can write the loader separately (we can specify Enforce: ‘pre’) or write the loader in the use array.

const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// Compress the CSS file
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
// Check the js code
// const EslintWebpackPlugin = require('eslint-webpack-plugin');
// process.env.NODE_ENV = 'development';
module.exports = {
  entry: './src/js/index.js'.// Where to put the packed files
  output: {
    filename: 'built.js'.path: resolve(__dirname, 'build'),},module: {
    rules: [
      / / deal with CSS
      {
        test: /.css$/,
        use: [
          // Package the CSS in js separately
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader'.options: {
              postcssOptions: {
                // WebPack 4 configuration
                // ident: 'postcss',
                // plugins: () = [
                // require('postcss-preset-env')()
                // ]
                // WebPack 5 configuration
                plugins: [require('postcss-preset-env'() [,},},},],},/ / SCSS processing
      {
        test: /.sass|scss$/,
        use: [
          // Package the CSS in js separately
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'postcss-loader'.options: {
              postcssOptions: {
                // WebPack 4 configuration
                // ident: 'postcss',
                // plugins: () = [
                // require('postcss-preset-env')()
                // ]
                // WebPack 5 configuration
                plugins: [require('postcss-preset-env')()],
              },
            },
          },
          'sass-loader',]},// Process the image
      {
        test: /.(png|gif|jpg|jpeg)/,
        use: [
          {
            loader: 'url-loader'.options: {
              limit: 8 * 1024.name: '[name].[hash:10].[ext]'.outputPath: 'static/imgs'.esModule: false,}},],type: 'javascript/auto',},// Process images in HTML
      {
        test: /.html$/,
        loader: 'html-loader',},// Process other resources
      { // Exclude CSS /js/ HTML resources
        exclude: /.(css|js|html|sass|json|png|gif|jpg|jpeg)$/,
        loader: 'file-loader'.options: {
          name: '[hash:10].[ext]'.outputPath: 'static/others',}},/ / {
      // // webpack checks the JS syntax
      // test: /.js$/,
      // exclude: /node_modules/,
      // loader: 'eslint-loader',
      // // When multiple loaders need to be loaded for a file, specify who to load first.
      // enforce: 'pre',
      // options: {
      // // Automatically fixes esLint errors
      // fix: true,
      / /},
      // },
      // Handle js compatibility
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'.options: {
              // Default: tell Babel what compatibility processing to do
              presets: [['@babel/preset-env', {
                // Load as needed
                useBuiltIns: 'usage'.// Specify the core-js version
                corejs: { version: 3 },
                // Specify which browser version is compatible
                targets: {
                  chrome: '60'.firefox: '60'.ie: '9'.safari: '10'.edge: '17',},}]],},}, {loader: 'eslint-loader'.options: {
              // Automatically fixes esLint errors
              fix: true,},},],},plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'.// Compress the HTML code
      minify: {
        // Remove whitespace
        collapseWhitespace: true.// Remove comments
        removeComments: true,}}),new MiniCssExtractPlugin({
      // Name the packaged file
      filename: 'static/css/built.css',}).new OptimizeCssAssetsWebpackPlugin(),
    // new EslintWebpackPlugin(),].mode: 'production'};Copy the code

The build code has been uploaded to github github.com/zhang-glitc…

Summarize the b stand is still silicon valley webpack www.bilibili.com/video/BV1e7…