What is Webpack?

In essence, Webpack is a static Module bundler for modern JavaScript applications. When WebPack works with an application, it recursively builds a Dependency graph containing every module the application needs, and then packages all of those modules into one or more bundles.

Core WebPack concepts

  • Entry: The entry point indicates which module WebPack should use as a starting point for building its internal dependency graph. Once at the entry point, WebPack finds out which modules and libraries are (directly and indirectly) dependent on the entry point.

Each dependency is then processed and finally exported to a file called bundles.

You can specify an entry point (or multiple entry points) by configuring the Entry property in webpack.config.js. The default value is./ SRC.

  • Output (output):outputProperty tells WebPack where to output what it createsbundles, and how to name these files, default is./dist. Basically, the entire application structure is compiled into a folder in the output path you specify. You can do this by specifying one in the configurationoutputField to configure these processes.
  • loader:loaderLet WebPack handle non-javascript files (WebPack itself only understands JavaScript). Loader can convert all types of files into valid modules that WebPack can handle, and then you can take advantage of WebPack’s packaging capabilities to process them.

In essence, WebPack Loader converts all types of files into modules that the application’s dependency diagram (and ultimately its bundle) can reference directly.

At a higher level, loader has two goals in the webpack configuration:

  1. testProperty that identifies the files or files that should be converted by the corresponding loader.
  2. useProperty indicating which loader should be used for conversion.
  • Plugins: Loaders are used to transform certain types of modules, while plug-ins can be used to perform a wider range of tasks. Plug-ins range from packaging optimization and compression to redefining variables in the environment. Plug-in interfaces are extremely powerful and can be used to handle a wide variety of tasks.

To use a plugin, you simply require() it and add it to the plugins array. Most plug-ins can be customized with options. You can also use the same plug-in multiple times for different purposes in a configuration file by using the new operator to create an instance of it.

  • model

By selecting either Development or Production to set the mode parameter, you can enable the optimization built into WebPack for that mode.

Build a React+TypeScript project with WebPack

  1. Initialize the project: Create a project folder and runnpm init -y Initialize.
  2. The installationwebpack,webpack-cli
Yarn add webpack webpack-cli --dev // (or use NPM)Copy the code
  1. Create a new lib/index.tsx file and write something:
console.log('hi');
Copy the code
  1. newwebpack.config.jsTo start the WebPack configuration, first add the entry configuration:
module.exports = {
    entry: {
        index: './lib/index.tsx'   
    },
}
Copy the code
  1. Tell Webpack how to interpret TSX files, addawesome-typescript-loader. First install:
yarn add awesome-typescript-loader --dev
Copy the code

Add configuration to webpack.config.js:

module.exports = {
    // ...
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    module: {
        rules: [
            {
                test: /.tsx?$/,
                loader: 'awesome-typescript-loader'
            }
        ]
    },
}
Copy the code
  1. Adding an Egress Configuration
const path = require('path') module.exports = { // ... Output: {path: path.resolve(__dirname, 'dist/lib'), // must be absolute path library: 'MyLibrary', // module name libraryTarget: 'umd', // Expose library to all module definitions}, module: {//... }},Copy the code
  1. addmode
module.exports = { //.... mode: "production", module: { //... }}Copy the code

The mode configuration item tells Webpack to use the built-in optimizations for the corresponding mode.

The mode configuration item supports the following two configurations:

  • developmentWill:process.env.NODE_ENVIs set todevelopment, enablingNamedChunksPluginNamedModulesPlugin
  • productionWill:process.env.NODE_ENVIs set toproduction, enablingFlagDependencyUsagePlugin.FlagIncludedChunksPlugin.ModuleConcatenationPlugin.NoEmitOnErrorsPlugin.OccurrenceOrderPlugin.SideEffectsFlagPluginUglifyJsPlugin
  1. configurationTypeScriptTSlintTo addtsconfig.jsontslint.json.
// tsconfig.json
{
  "compilerOptions": {
    "outDir": "dist",
    "declaration": true,
    "baseUrl": ".",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": ".",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "importHelpers": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "noUnusedLocals": true
  },
  "include": [
    "lib/**/*"
  ],
  "exclude": [
    "node_modules",
    "build",
    "dist",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts",
    "*.js"
  ]
}
Copy the code
// tslint.json
{
  "extends": ["tslint:recommended", "tslint-react"],
  "rules": {
    "no-console": [false, "log", "error"],
    "jsx-no-multiline-js": false,
    "whitespace": false,
    "no-empty-interface": false,
    "space-before-function-paren": false,
    "no-namespace": false,
    "label-position": false,
    "quotemark": [true, "single", "jsx-double"],
    "member-access": false,
    "semicolon": [true, "always", "ignore-bound-class-methods"],
    "no-unused-expression": [true, "allow-fast-null-checks"],
    "member-ordering": false,
    "trailing-comma": false,
    "arrow-parens": false,
    "jsx-self-close": false,
    "max-line-length": false,
    "interface-name": false,
    "no-empty": false,
    "comment-format": false,
    "ordered-imports": false,
    "object-literal-sort-keys": false,
    "eofline": false,
    "jsx-no-lambda": false,
    "no-trailing-whitespace": false,
    "jsx-alignment": false,
    "jsx-wrap-multilines": false,
    "no-shadowed-variable": [
      false,
      {
        "class": true,
        "enum": true,
        "function": false,
        "interface": false,
        "namespace": true,
        "typeAlias": false,
        "typeParameter": false
      }
    ]
  },
  "linterOptions": {
    "exclude": [
      "config/**/*.js",
      "node_modules/**/*.ts",
      "coverage/lcov-report/*.js"
    ]
  }
}
Copy the code

Now, execute NPX webpack and see the escaped index.js file in the dist/lib folder.

  1. View the page in your browser

View the page need to have HTML file, because each time generated JS file name may be different, always cannot manually modify the HTML, so use the html-webpack-plugin plug-in to help us automatically insert script tags.

First install the HTmL-webpack-plugin

yarn add html-webpack-plugin --dev
Copy the code

Configuration webpack. Config. Js

const HtmlWebpackPlugin = require('html-webpack-plugin'); Module.exports = {// exports... plugins: [ new HtmlWebpackPlugin({ title: 'React-app', template: 'index.html' }) ] }Copy the code

Create index.html in the root directory

<! DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, Initial - scale = 1.0 "> < title > < % = htmlWebpackPlugin. Options. The title % > < / title > < / head > < body > < div id =" root "> < / div > < / body > </html>Copy the code
  1. usewebpack-dev-serverAutomatic packaging

Run yarn add webpack-dev-server –dev to install webpack-dev.

Running NPX webpack-dev-server opens a port that asks for the most recently compiled source string (stored in memory).

  1. Configure the development environment and production environment separately

Create webpack.config.dev.js and webpack.config.prod.js.

According to project requirements and usage methods, for example, this project is to develop a React component library, so there is no need to download the React dependency. In the corresponding configuration of the production environment, add React externals to reduce the size of the packaged code. Keep the common configurations of production and development environments in webpack.config.js, and then configure webpack.config.dev.js and webpack.config.prod.js respectively according to project requirements.

webpack.config.js

const path = require('path')
module.exports = {
  entry: {
    index: './lib/index.tsx'
  },
  resolve: {
    extensions: ['.ts'.'.tsx'.'.js'.'.jsx'],},output: {
    path: path.resolve(__dirname, 'dist/lib'),
    library: 'MyLibrary'.libraryTarget: 'umd',},module: {
    rules: [{test: /\.tsx? $/,
        loader: 'awesome-typescript-loader'
      },
      {
        test: /\.svg$/,
        loader: 'svg-sprite-loader'}, {test: /\.scss$/,
        use: ['style-loader'.'css-loader'.'sass-loader']}]},}Copy the code

Webpack.config.dev.js is used in the development environment

const base = require('./webpack.config')   // Merge the shared configuration items
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = Object.assign({}, base, {
    mode: 'development'.entry: {
        example: './example.tsx',},plugins: [
        new HtmlWebpackPlugin({
            title: 'React-app'.template: 'example.html'})],})Copy the code

Webpack.config.prod. js is used in production environments

const base = require('./webpack.config')
module.exports = Object.assign({}, base, {
    mode: 'production'.externals: {
        react: {
            commonjs: 'react'.commonjs2: 'react'.amd: 'react'.root: 'React',},'react-dom': {
            commonjs: 'react-dom'.commonjs2: 'react-dom'.amd: 'react-dom'.root: 'ReactDOM',}}})Copy the code

Add to package.json file

  "scripts": {
    "start": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
    "test": "cross-env NODE_ENV=test jest --config=jest.config.js --runInBand",
  },
Copy the code

You can run the yarn start command to run NPX webpack-dev-server and specify the configuration file as webpack.config.dev.js.

Run NPX webpack using the yarn build command and specify the configuration file as webpack.config.prod.js. (Cross-env is for Windows and Mac compatibility).


The webpack configuration of this project is basically completed. In the subsequent development, corresponding configuration can only be added according to requirements and error reports. Only with an understanding of WebPack can you make the most appropriate configuration for your needs.

Reference for this article:

  • Webpack Chinese document
  • Deep Unlock Webpack series (Basics)