preface

In today’s front-end development, we use a lot of packaging tools may be, of course, Webpack is one of them, so the configuration in Webpack is actually a lot of, so today to sort out the common configuration and its role.

How to start

We’ll create an empty folder, use NPM init webpack-demo, press Enter, and it will create a package.json file in our folder

Install WebPack4 in the current project

We can execute this command: NPM install webpack-cli webpack -d

So let’s assume that the latest version of WebPack is 4.1.2. What if we don’t want to install the latest version and choose manually?

NPM info webpack After executing this command, the console lists all available versions of Webpack

Find the version we want to install and record the version number (assuming we want to install webpack4.16.5)

We can then use NPM install [email protected] -d to install the specified version of Webpack.

Start the configuration

The default configuration is officially provided in Webpack4, but sometimes it doesn’t meet our needs. If we want to configure it ourselves, we can create a webpack.config.js file in the project directory to write our own configuration

Configuration is introduced

const path = require('path')
module.exports = {
    mode: 'production'.entry: {
        main: './index.js'
    },
    output: {filename: 'bundle.js'.path: path.resolve(__dirname,'build')}}Copy the code

The generated file should be placed in the build folder. The generated file is called bundle.js. Note that path must be an absolute path. Therefore, we need to introduce nodeJS path module to assist us. If mode is production, it means that the packaged JS code is compressed. Of course, the code will not be compressed if development is entered here

Loader

The reason why we need to use Loader is that webapck only knows how to package JS files by default, but does not know how to package pictures, fonts and other types of files. Therefore, we need to use Loader to assist WebPack to process special files when packaging.

Image file packaging configuration

We configure on top of that

const path = require('path')
module.exports = {
    mode: 'development'.entry: {
        main: './index.js'
    },
    module: {rules: [{
          test: /\.jpg$/.use: {
            loader:'file-loader'}}},output: {filename: 'bundle.js'.path: path.resolve(__dirname,'build')}}Copy the code

Here we add a module configuration, which actually tells Webpack how to package modules, rules refers to the rules for packaging modules, test refers to the matching rules, use refers to which loader is used for processing, so here we use the official recommended file-loader. Loader, in fact, it can handle images and other files, so this configuration can be successfully packaged.

Don’t forget to install file-loader dependencies, NPM install file-loader -d

Webpack dev – server configuration

Using DevServer can improve our development efficiency, such as hot updates

devServer: {
    contentBase: './dist',
    open: 'true',
    port: 8080,
    hot: true,
    hotOnly:true
  },
Copy the code

CSS packaging configuration

module: {
    rules: [
      {
        test: /\.(css|scss)$/,
        use: ['style-loader', {
          loader: 'css-loader',
          options: {
            importLoaders: 2
          }
        },
          'sass-loader'.'postcss-loader']]}},Copy the code

Postcss-loader: PostCSs-loader: postCSs-loader: PostCSs-loader: PostCSs-Loader: PostCSs-Loader: PostCSs-Loader: PostCSs-Loader: PostCSs-Loader The configuration here roughly means: I prefixed CSS with postCSS-loader, then gave sass-Loader to compile our SASS into normal CSS, then gave it to our CSS-Loader, and then gave it to our style-loader to mount our styles on the page.

ImportLoaders: 2 What does this mean?

We might have the following scenario: If an SCSS file is imported from another SCSS file, it is possible that the following two loaders (sass-loader, postCSS-loader) will not be used when packaging, and csS-loader will be directly used. So if we want the SCSS file to be imported to also go through the next two loaders we should configure this configuration so that WebPack knows what to do.

Package font files such as iconfont

module: {
    rules: [
      {
        test: /\.(eot|ttf|svg|woff|woff2)$/,
        use: {
          loader: 'file-loader'}}}]Copy the code

We can use file-loader to package files

Plugins

Introduction to the

Plugin can do some things for you when the WebPack is running at a certain point

HtmlwebpackPlugin

const HtmlwebpackPlugin = require('html-webpack-plugin');
plugins: [new HtmlwebpackPlugin({
    template: 'src/index.html',
    filename:'index.html'
})]
Copy the code

Here we use an HtmlwebpackPlugin. We specify which file to use for the template and the filename of the package

CleanwebpackPlugin

const CleanwebpackPlugin = require('clean-webpack-plugin');
plugins: [new HtmlwebpackPlugin({
    template: 'src/index.html',
    filename:'index.html'
}),new CleanwebpackPlugin()]
Copy the code

The CleanwebpackPlugin removes everything in the dist folder at packaging time. It reduces the frequency of our manual operations

babel

Our project will inevitably have to do some compatibility work, so we are going to use Babel to convert our ES6 code to ES5 code. We should install @babel/ PRESET -env and babel-Polyfill dependencies first

module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, '.. /src'),
        loader: 'babel-loader',
        options:{
            presets:[['@babel/preset-env',{
                useBuiltIns:"usage"}}}}]]]Copy the code

This configuration ‘@babel/preset-env’ is just a preset for ES6 to ES5, and we need to introduce babel-polyfill at the top of main.js, which means to mimic some functions that are not available in ES6 in ES5. UseBuiltIns :” Usage “This means that during the simulation, only the es6 functions used in our project are simulated.

tree-shaking

In Webpack we can do tree shaking for code that we have introduced but are not using (note that this only works for esModule) we need to configure it in package.json: SideEffects :[‘ babel-polyfill ‘] then packaged to remove all references that are not referenced except babel-polyfill

code-splitting

We need to split the packaged file into several small files, so as to prevent the user from invalidation of the cache and having to download a large file again when updating the code

optimization: {
    runtimeChunk: {
      name: 'runtime'
    },
    splitChunks: {
      chunks: 'all',// Sync async are packaged cacheGroups: {vendors: {vendors: {test: /[\\/]node_modules[\\/]/,
          priority: -10,
          filename: 'vendors.js'}}}},Copy the code

CSS file code segmentation

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'We need to install optimization: {usedExports: true.// tree shaking
    minimizer: [new OptimizeCssAssetsPlugin({})]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css'.chunkFilename: '[name].chunk.css'})]Copy the code