Manually build the project from 0-1 webpack

Manually build the project from 0-1 webpack

1. Install npm package

npm install webpack-cli webpack -D

2. Create a configuration file under the specified folder

We can create the corresponding configuration file in the root directory, or in the directory we want to put (eg: /config)

We can write three configuration files in order to distinguish the environment etc.

# at /config 
touch webpack.common.js
touch webpack.dev.js
touch webpack.prod.js
复制代码

2.5 Configure all es modules (not required, optional)

The value package.jsonof the configuration property in , to specify that all files should be parsed with.typemodulejses module

# package.json
{
"type": "module" 
}
复制代码

It should be noted here that if we use it, it is es modulenot supported __dirname. __filenameWhen we look for the address of the file definition, we can use it directly import.meta.url(the address of the current file), and use the URL in the urlmodule to generate the desired content instead of using __dirname, __filenameetc. For example:

import { URL } from 'url'
export default {
  entry: {
    // index: path.join(__dirname, "../src/index.js")
    index: new URL('../src/index.js', import.meta.url).pathname,
  },
  output: {
    filename: '[name].[contenthash:4].js',
    // path: path.join(__dirname, '../dist') // distribution 发行版
    path: new URL('../dist/', import.meta.url).pathname,
  }
}

复制代码

3. Configure scripts related packages

After the configuration, since we want to merge the configuration folders, and the project may need to be started on different platforms, we can install the following two toolkits

npm install webpack-merge cross-env -D
复制代码

webpack-mergeis used to merge configuration files

cross-envUsed to deal with compatibility issues of different platform systems in the command line

4. Generate HTML file with configuration content

Install first html-webpack-pluginto process build htmlfiles

npm install html-webpack-plugin -D

At the same time, in order to automatically start the server for development and debugging, we can use

npm install webpack-dev-server -D

to deal with local service issues

5. Support front-end framework, react as an example

reference package first

npm install react react-dom -S

Configure build tools

npm install babel-loader @babel/core @babel/preset-react -D

// .babelrc 文件
{
	"presets": ["@babel/preset-react"] // preset 是官方配置好的plugins集合,另外配置了一些options
}
复制代码
// webpack.common.js 配置文件
module: {
		rules: [
			{
				test: /\.(js|jsx)$/,
				loader: 'babel-loader'
			}
		]
	}
复制代码

6. Support ts

npm i @babel/preset-typescript -D

// .babelrc 文件
{
	"presets": ["@babel/preset-react", "@babel/preset-typescript"]// preset 是官方配置好的plugins集合,另外配置了一些options
}
复制代码
	module: {
		rules: [
			{
				test: /\.(js|jsx|ts|tsx)$/, // 增加ts类型支持
				loader: 'babel-loader'
			}
		]
	}
复制代码

7. Support css and preprocessor

npm i style-loader css-loader sass sass-loader less less-loader

	module: {
		rules: [
			{
				test: /\.(js|jsx|ts|tsx)$/,
				loader: 'babel-loader'
			},
			{
				test: /\.css$/,
				use:['style-loader','css-loader']
			},
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
			{
				test: /\.(sass|scss)$/,
				use:['style-loader','css-loader', 'sass-loader']
			}
		]
	}
复制代码

It should be noted here that if one loader is introduced, we write it directly lodader. If we want to introduce more than one, use useit, and usethe execution order of the loaders in the array is executed from right to left (similar to popping a loader each time for execution).

8. Support img import, etc.

npm install url-loader file-loader -D

  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        loader: 'babel-loader',
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader'],
      },
      {
        test: /\.(sass|scss)$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [{ loader: 'url-loader', options: { limit: +10240 } }],
      },
      { test: /\.(woff|woff2|eot|ttf|otf)$/, use: 'file-loader' },
    ],
  }
复制代码

file-loaderThe url-loaderdifference between and

file-loader is used to parse images and fonts

url-loader 也可以用来处理图片和字体,还可以设置较小资源自动 base64

9. 支持 antd

npm install antd -S

如果我们引入了antd/dist/antd.less会报错误,刚刚不是已经处理过less的编译了吗?为什么还会报错呢?

先不着急,我们看看报错的说明

image-20220321080946464.png 这是提示我们在less文件中不支持javascript语法。我们需要在less-loader中进行配置使其支持js

      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', {
					loader: 'less-loader',
					options: {
						lessOptions: {
							javascriptEnabled: true
						}
					}
				}],
      },
复制代码

关于javscriptEnabled disprecated回答

10. 美化:给Terminal编译过程加个进度条

npm i webpackbar -D

webpackbar是一个plugin, 可以用来显示编译打包进度。

// webpack.dev.config
plugins: [new Webpackbar()],
复制代码

webpackbar

11. 优化

external优化

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。此功能通常对 library 开发人员来说是最有用的,然而也会有各种各样的应用程序用到它。

external 能防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)

我们可以从CDN引入react,react-dom,而不是打包。

  externals: {
    // 外部扩展
    react: 'React',
    'react-dom': 'ReactDOM',
  },
复制代码

这样可以很好地优化打包的时间

external

stats 对象

stats 选项让你更精确地控制 bundle 信息该怎么显示。如果只是想要获取某部分 bundle 的信息,使用 stats 选项是比较好的折衷方式。

stats.modules : 告知 stats 是否添加关于构建模块的信息。默认为true

stats

TerserWebpackPlugin

该插件使用 terser 来压缩 JavaScript。

webpack v5 开箱即带有最新版本的 terser-webpack-plugin。如果你使用的是 webpack v5 或更高版本,同时希望自定义配置,那么仍需要安装 terser-webpack-plugin。如果使用 webpack v4,则必须安装 terser-webpack-plugin v4 的版本。

npm install terser-webpack-plugin esbuild --save-dev

  optimization: {
		minimizer: [
			new TersetWebpackPlugin({
				extractComments:false,
				minify: TersetWebpackPlugin.esbuildMinify // esbuild 提速
			}),
		]
	},
复制代码

TerserWebpackPlugin

css-mini-extract-plugin

这个插件将 CSS 提取到单独的文件中。它为每个包含 CSS 的 JS 文件创建一个 CSS 文件。它支持 CSS 和 sourcemap 的按需加载。只在webpack v5及以后版本支持。

npm i mini-css-extract-plugin -D

用法不再赘述,直接看文档

mini-css-extract-plugin

clean-webpack-plugin

A webpack plugin to remove/clean your build folder(s).

const webpackConfig = {
    plugins: [
        /**
         * All files inside webpack's output.path directory will be removed once, but the
         * directory itself will not be. If using webpack 4+'s default configuration,
         * everything under <PROJECT_DIR>/dist/ will be removed.
         * Use cleanOnceBeforeBuildPatterns to override this behavior.
         *
         * During rebuilds, all webpack assets that are not used anymore
         * will be removed automatically.
         *
         * See `Options and Defaults` for information
         */
        new CleanWebpackPlugin(),
    ],
};
复制代码

npm i clean-webpack-plugin -D

clean-webpack-plugin

css-minimizer-webpack-plugin

This plugin uses cssnano to optimize and minify your CSS.

npm i css-minimizer-webpack-plugin -D

css-minimizer-webpack-plugin

happyPack

由于 JavaScript 是单线程模型,我们可以通过使用多进程,启用多核 CPU 的能力。happyPack的思想是使用多个子进程去解析和编译JS,css,等,这样就可以并行处理多个子任务,多个子任务完成后,再将结果发到主进程中

npm install happypack -D

1. 创建 happypack 插件实例
// webpack.common.js
// import HappyPack from 'happypack'
// import os from 'os'
// const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length})

  plugins: [
    new HappyPack({
      id: 'babel', // 唯一标识id, 表示当前实例,后面会在 module/rules中进行使用
      loaders: ['babel-loader?cacheDirectory'], // 和module/rules中的 Loader用法一致
      threads: 3, // 代表开启几个子进程去处理这一类型的文件,默认是3个,类型必须是整数。
      threadPool: happyThreadPool, //  // 使用共享进程池中的子进程去处理任务
    }),
  ],
复制代码
2. 在 Loder中使用
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        // loader: 'babel-loader',
        // 在 Loader 配置中,所有文件的处理都交给了 happypack/loader 去处理,使用紧跟其后的 querystring ?id=babel 去告诉 happypack/loader 去选择哪个 HappyPack 实例去处理文件。
        use: ['happypack/loader?id=babel'],
        exclude: /node_modules/,
      },
    ]
  },
}
复制代码

happypack

  1. TODO: 后续补充更新,欢迎留言发问,催更

    eslint

    CI/CD

    pre commit 检查

Guess you like

Origin juejin.im/post/7078664566531588110