preface

In the last part of “The Road to Learning Webpack5 (Basics)”, I introduced what Webpack is, why I chose Webpack, and the basic concepts of Webpack.

Starting from practice, this paper will use Webpack to build a basic project supporting modular development in Chapter 1 “Basic Configuration”, and use Webpack to build a SASS + TS + React project in Chapter 2 “Advanced Configuration”.

This article relies on the following WebPack version information:

1. Basic configuration

Next, configure a basic Webpack together.

The following functions will be supported:

  • Separate the configuration of development environment and production environment;
  • Modular development;
  • SourceMap location warning and error;
  • Dynamically generate HTML5 files that introduce bundle.js;
  • Real-time compilation;
  • Package compilation, package command.

Webpack Demo0 webpack Demo0

1. Create a project

Create an empty project:

// Create the webpack-demo folder
mkdir webpack-demo

// Go to the webpack-demo directory
cd ./webpack-demo

// Initialize the project
npm init -y
Copy the code

Create 2 js files and develop modularity:

// Enter the project directory
cd ./webpack-demo

// Create the SRC folder
mkdir src

// Create the js file
touch index.js
touch hello.js
Copy the code

Index. Js:

// index.js

import './hello.js'

console.log('index')
Copy the code

Hello. Js:

// hello.js
console.log('hello webpack')
Copy the code

The project structure is as follows:

- src
    - index.js
    - hello.js
- package.json
- node_modules
Copy the code

2. Install

  1. Install the Node

The Node version must be the latest. You are advised to use NVM to manage the Node version.

Updating Node.js to the latest version will also help improve performance. In addition, updating your package management tools (such as NPM or YARN) to the latest version will also help improve performance. Newer versions build more efficient module trees and speed up parsing.

  • Node: indicates the installation address

  • NVM: indicates the installation address

The version information I installed is as follows:

  • The node v14.17.3
  • NPM v6.14.13)
  1. Install webpack
npm install webpack webpack-cli --save-dev
Copy the code

3. Create a configuration file

There is a big difference in the build goals between the development and production environments. Write separate WebPack configurations for each environment for clear and concise code.

// Enter the project directory
cd ./webpack-demo

// Create the config directory
mkdir config

// Go to the config directory
cd ./config

// Create a common environment profile
touch webpack.common.js

// Create the development environment profile
touch webpack.dev.js

// Create the production environment configuration file
touch webpack.prod.js
Copy the code

webpack-merge

Use Webpack-Marge to combine common and environment-specific configurations.

Install webpack – merge:

npm i webpack-merge -D
Copy the code

General environment Configuration:

// webpack.common.js

module.exports = {} // Do not add the configuration

Copy the code

Development environment configuration:

// webpack.dev.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {}) // Do not add the configuration

Copy the code

Production environment configuration:

// webpack.prod.js

const { merge } = require('webpack-merge')
const common = require('./webpack.common')

module.exports = merge(common, {}) // Do not add the configuration

Copy the code

The project structure is as follows:

- config
    - webpack.common.js
    - webpack.dev.js
    - webpack.prod.js
- src
    - index.js
    - hello.js
- package.json
- node_modules
Copy the code

4. Entry

The entry point indicates which module webPack should use to start building its internal dependency graph. After entering the entry point, WebPack will find out which modules and libraries the entry point (directly and indirectly) depends on.

In this case, using SRC /index.js as the project entry, WebPack starts with SRC /index.js and looks for all dependent modules.

Modify webpack.com mom. Js:

module.exports = merge(common, {
  / / the entry
  entry: {
    index: './src/index.js',}})Copy the code

5. Output

The output property tells WebPack where to output the bundles it creates and how to name the files.

The output of the production environment needs to distinguish the versions and changes by the Contenthash value to achieve the effect of clear cache, while the local environment does not introduce Contenthash for the sake of building efficiency.

Add paths.js, encapsulate path method:

const fs = require('fs')
const path = require('path')

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath= > path.resolve(appDirectory, relativePath);

module.exports = {
  resolveApp,
  appPublic: resolveApp('public'),
  appHtml: resolveApp('public/index.html'),
  appSrc: resolveApp('src'),
  appDist: resolveApp('dist'),
  appTsConfig: resolveApp('tsconfig.json'),}Copy the code

Modify the development environment configuration file webpack.dev.js:

module.exports =  merge(common, {
  / / output
  output: {
    // the bundle file name
    filename: '[name].bundle.js'.// The bundle file path
    path: resolveApp('dist'),
    
    // Clear the directory before compilation
    clean: true}})Copy the code

Modify the production environment configuration file webpack.prod.js:

module.exports =  merge(common, {
  / / output
  output: {
    // The name of the bundle file.
    filename: '[name].[contenthash].bundle.js'.// The bundle file path
    path: resolveApp('dist'),
    
    // Clear the directory before compilation
    clean: true}})Copy the code

The placeholder for the preceding filename is explained as follows:

  • [name]– chunk name (for example[name].js -> app.js). If the chunk has no name, its ID is used as the name
  • [contenthash]– Output the md4-hash of the file contents (for example[contenthash].js -> 4ea6ff1de66c537eb9b2.js)

6. Mode

The Mode configuration option tells WebPack to use the built-in optimizations for the appropriate mode.

options describe
development willDefinePlugin 中 process.env.NODE_ENVIs set todevelopment. Enable valid names for modules and chunks.
production willDefinePlugin 中 process.env.NODE_ENVIs set toproduction. Enable deterministic obfuscated names for modules and chunks,FlagDependencyUsagePlugin.FlagIncludedChunksPlugin.ModuleConcatenationPlugin.NoEmitOnErrorsPlugin 和 TerserPlugin 。

Modify the development environment configuration file webpack.dev.js:

module.exports =  merge(common, {
  // Development mode
  mode: 'development',})Copy the code

Modify the production environment configuration file webpack.prod.js:

module.exports =  merge(common, {
  // Production mode
  mode: 'production',})Copy the code

7. Source Map

When WebPack packages source code, it can be difficult to trace errors and warnings to their original location in the source code.

To make tracking errors and warnings easier, JavaScript provides Source Maps, which maps compiled code back to the original source code.

Modify the development environment configuration file webpack.dev.js:

module.exports =  merge(common, {
  // Open source map, compile and debug
  devtool: 'eval-cheap-module-source-map',})Copy the code

There are many options available for Source Map. In this example, eval-cheap-mode-source-map is selected

Note: To speed up production packaging, devTool is not configured for production.

After the above configuration is complete, you can package and compile with NPX webpack –config config/webpack.prod.js.

When compiled, this directory structure is generated:

8. HtmlWebpackPlugin

NPX webpack –config config/webpack.prod.js — NPX webpack –config config/webpack.prod.js — NPX webpack –config config/webpack.

The HtmlWebpackPlugin is introduced to generate an HTML5 file that includes all the WebPack packages in the body using the script tag.

Installation:

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

Modify the general environment configuration file webpack.commom.js:

module.exports = {
  plugins: [
    // Generate HTML to automatically import all bundles
    new HtmlWebpackPlugin({
      title: 'release_v0',})],}Copy the code

NPX webpack –config config/webpack.prod.js

The bundle.js file is dynamically introduced as index. HTML:

<! DOCTYPEhtml>
<html>
 <head>
  <meta charset="utf-8" />
  <title>release_v0</title>
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <script defer="defer" src="index.468d741515bfc390d1ac.bundle.js"></script>
 </head>
 <body></body>
</html>
Copy the code

9. DevServer

While it would be cumbersome to run NPX webpack –config config/webpack.prod.js manually every time the code is compiled, webpack-dev-server helps us compile the code automatically after changes are made.

Webpack-dev-server provides a basic Web server with real-time reload capabilities.

The default configuration for webpack-dev-server is conpress: true, enabling GZIP compression for each static file.

Installation:

npm install --save-dev webpack-dev-server
Copy the code

Modify the development environment configuration file webpack.dev.js:

module.exports = merge(common, {
  devServer: {
    // Tell the server where to serve the content, only if you want to serve static files.
    contentBase: './dist',}})Copy the code

NPX webpack Serve –open –config config/webpack.dev.js can be compiled in real time.

The effect is as follows:

10. Run the following command

After the above configuration files are completed, optimize webPack real-time compilation, packaging compilation instructions.

Cross-env configures environment variables to distinguish between development and production environments.

Installation:

npm install --save-dev cross-env
Copy the code

Modify the package. The json:

{
    "scripts": {
        "dev": "cross-env NODE_ENV=development webpack serve --open --config config/webpack.dev.js"."build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js"}},Copy the code

You can now run the Webpack directive:

  • NPM run dev: local build;
  • NPM Run build: Production packaging.

This completes a simple project that supports modular development based on WebPack compilation.

Source address: Webpack Demo0

Two, advanced configuration

This chapter will continue to improve the configuration, and build a SASS + TS + React project with Webpack on the basis of the above configuration.

The following functions will be supported:

  • Load image;
  • Load fonts;
  • Load the CSS;
  • Use SASS;
  • PostCSS is used to automatically add prefixes to CSS rules, parse the latest CSS syntax, and introduce CSS-modules to solve global name conflicts.
  • Use the React;
  • Use the TypeScript.

Webpack Demo1, Demo1, Demo1

1. Load the Image

In WebPack 5, we can use the built-in Asset Modules to mix images into our system.

Modify the general environment configuration file webpack.commom.js:

const paths = require('./paths');
module.exports = {
    module: {
        rules: [{test: /\.(png|svg|jpg|jpeg|gif)$/i,
            include: paths.appSrc,
            type: 'asset/resource',},],},}Copy the code

In the actual development process, it is recommended to upload large images to CDN to improve the loading speed.

2. Load the Font (Font)

Use Asset Modules to receive font files.

Modify the general environment configuration file webpack.commom.js:

module.exports = {
    module: {
        rules: [{test: /.(woff|woff2|eot|ttf|otf)$/i,
               include: [
                  resolveApp('src')],type: 'asset/resource',},]}}Copy the code

Here I found that I did not add the configuration of the TTF file, but also can introduce the font without error, do not know what the problem is, first record, there are know the reason for the big guy to move to the comment area.

In the actual development process, it is recommended to compress the font file and upload it to CDN to improve the loading speed. If the text of the configured font is fixed, the font file can also be generated for the fixed text, and the size of the font file can be greatly reduced.

3. Load the CSS

To import a CSS file in a JavaScript module, you need to install and configure a style-loader and css-Loader.

3.1 style-loader

A style-loader is used to insert CSS into the DOM, automatically inserting styles into the DOM by using multiple

versions.

3.2 css-loader

The CSS-Loader handles @import and URL () in the same way that JS parses import/require(), allowing CSS to be modular.

3.3 Installation and Configuration

Install the CSS dependencies:

npm install --save-dev style-loader css-loader
Copy the code

Modify the general environment configuration file webpack.commom.js:

const paths = require('./paths');
module.exports = {
    module: {
        rules: [{test: /\.css$/,
                include: paths.appSrc,
                use: [
                  // Generate the JS string as a style node
                  'style-loader'.// Convert CSS to CommonJS module
                  'css-loader',],},]}}Copy the code

4. Use SASS

4.1 Sass

Sass is a CSS enhancer that adds variables, nesting, blending, importing, and other advanced functions to the CSS syntax.

4.2 sass-loader

The sass-Loader loads the Sass/SCSS files and compiles them into CSS.

4.3 Installation and Configuration

Install SASS dependencies:

npm install --save-dev sass-loader sass 
Copy the code

Modify the general environment configuration file webpack.commom.js:

const paths = require('./paths');
module.exports = {
    module: {
        rules: [{test: /.(scss|sass)$/,
        include: paths.appSrc,
        use: [
          // Generate the JS string as a style node
          'style-loader'.// Convert CSS to CommonJS module
          'css-loader'.// Compile Sass into CSS
          'sass-loader',]},Copy the code

5. Use PostCSS

5.1 PostCSS

PostCSS is a tool for converting CSS code with JavaScript tools and plug-ins.

  • You can automatically add prefixes to CSS rules.
  • Translate the latest CSS syntax into one that most browsers can understand;
  • Css-modules resolves global name conflicts.

5.2 postcss-loader

Postcss-loader Uses the PostCSS to process CSS loaders.

5.3 Installation and Configuration

The PostCSS installation dependencies are as follows:

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

Modify the general environment configuration file webpack.commom.js:

const paths = require('./paths');
module.exports = {
    module: {
        rules: [{test: /\.module\.(scss|sass)$/,
            include: paths.appSrc,
            use: [
              // Generate the JS string as a style node
              'style-loader'.// Convert CSS to CommonJS module
              {
                loader: 'css-loader'.options: {
                  // Enable CSS Modules features
                  modules: true.importLoaders: 2.// 0 => no loaders (default);
                  // 1 => postcss-loader;
                  // 2 => postcss-loader, sass-loader}},// Compile PostCSS into CSS
              {
                loader: 'postcss-loader'.options: {
                  postcssOptions: {
                    plugins: [[// Postcss-preset -env contains the autoprefixer
                        'postcss-preset-env',],],},},},// Compile Sass into CSS
              'sass-loader',],},],},}Copy the code

To improve the building efficiency, include is specified for loader. By using the include field, loader is applied only to the modules that need to be converted.

Use React + TypeScript

In order to make the project configuration more flexible, we do not use create-reate-app to build the project with one click, but build the configuration items corresponding to React manually.

Install React

npm i react react-dom @types/react @types/react-dom -D
Copy the code

Installing TypeScript

npm i -D typescript esbuild-loader
Copy the code

To improve performance, the latest ESbuild-loader is chosen instead of the traditional TS-Loader.

Modify the general environment configuration file webpack.commom.js:

const paths = require('./paths');
 module.exports = {
    resolve: {
        extensions: ['.tsx'.'.ts'.'.js'],},module: {
        rules: [{test: /\.(js|ts|jsx|tsx)$/,
                include: paths.appSrc,
                use: [{loader: 'esbuild-loader'.options: {
                      loader: 'tsx'.target: 'es2015',},}]},]}}Copy the code

TypeScript is a superset of JavaScript with an added type system that can be compiled into normal JavaScript code.

New TypeScript configuration file tsconfig.json to be compatible with TypeScript files:

{
    "compilerOptions": {
        "outDir": "./dist/"."noImplicitAny": true."module": "es6"."target": "es5"."jsx": "react"."allowJs": true."moduleResolution": "node"."allowSyntheticDefaultImports": true."esModuleInterop": true,}}Copy the code

If you want to keep something like import_ from ‘lodash’ in TypeScript; Grammar is to make it as a default way of import, need in the file tsconfig. Json set in the “allowSyntheticDefaultImports” : true and “esModuleInterop” : true.

Note: There are pits

1. "allowSyntheticDefaultImports": trueconfiguration

TypeScript configuration file tsconfig. Json need to add “allowSyntheticDefaultImports” : True configuration, otherwise you will be prompted can only be the default – imported using the ‘allowSyntheticDefaultImports’ flag.

{
    "compilerOptions": {
        "allowSyntheticDefaultImports": true}},Copy the code

Do not add “allowSyntheticDefaultImports” : true error information is as follows:

2. The TSX and JSX cannot be used together

JSX file in TSX

Above we completed a Webpack-based SASS + TS + React project.

Source address: Webpack Demo1

Third, summary

This article from the Webpack basic configuration, Webpack advanced configuration of two perspectives, from the Webpack practice, and you understand Webpack.

Stay tuned for the next part of learning the Webpack5 Path (Optimization), which will continue to optimize your project configuration and try to build an optimal Webpack configuration.

Source code:

  • webpack Demo0
  • webpack Demo1

I hope it can help you, thanks for reading ~

Don’t forget to encourage me with a thumbs-up, pen refill ❤️

Past wonderful

  • Learn the Webpack5 Path (Basics)

The resources

  • webpack.docschina.org/