Webpack 学习笔记

793 阅读2分钟

写在最前面

石川Blue老师《Webpack从入门到精通》学习的系列课程,说的蛮好边学变做下了笔记。 ke.qq.com/course/4142…

基础

安装

www.webpackjs.com/

  1. 初始化
npm init -y
  1. 安装模块
npm i webpack webpack-cli webpack-dev-server css-loader style-loader postcss-loader autoprefixer sass-loader node-sass file-loader url-loader babel-loader @babel/core @babel/preset-env html-webpack-plugin eslint eslint-loader stylelint stylelint-webpack-plugin stylelint-config-standard -D

webpack.config.js

const path = require('path');

module.exports = {
  mode: 'development',// production
  entry: './src/js/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

多套配置

1. 添加命令 package.json

// package.json
{
	"scripts": {
  	+ "start": "webpack-dev-server --env.development --open",
    "build": "webpack --env.production"
  }
}

2. 重构 webpack.config.js

// 公共

module.exports=(env, argv) => {
    env = env || {development : true}
    return {
        entry: './src/js/index.js',
        module: { ... },
        // 引入配置
        ...env.development ? require('./config/webpack.development') : require('./config/webpack.production')
    }
}

3.webpack.development.js

// src/webpack.development.js

const path = require('path');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports={
    mode: 'development',
    output: {
        filename: 'bundle.js'
    },
    plugins: [
        new StyleLintPlugin({
            files: ['**/*.css','**/*.scss']
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname,'../index.html')
        })
    ],
    devtool: 'source-map'
}

4.webpack.production.js

// src/webpack.production.js

const path = require('path');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports={
    mode: 'production',
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: 'bundle.min.js'
    },
    plugins: [
        new StyleLintPlugin({
            files: ['**/*.css','**/*.scss']
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname,'../index.html')
        })
    ]
}

5. 完成

完整 webpack.config.js 配置

module.exports=(env, argv) => {
    env = env || {development : true}
    return {
        entry: './src/js/index.js',
        module: {
            rules: [
                // js eslint -> babel
                {
                    test: /\.js$/i,
                    exclude: /node_modules/,
                    use: [
                        {
                            loader: 'babel-loader',
                            options: {
                                presets: ['@babel/preset-env']
                            }
                        }, {
                            loader: 'eslint-loader'
                        }
                    ]
                },

                // css css -> style
                {
                    test: /\.css$/i,
                    use: [
                        "style-loader",
                        "css-loader",
                        {
                            loader: "postcss-loader",
                            options: {
                                plugins: [
                                    require("autoprefixer")
                                ]
                            }
                        }
                    ]
                },

                // scss
                {
                    test: /\.scss$/i,
                    use: [
                        "style-loader",
                        "css-loader",
                        "sass-loader"
                    ]
                },

                // images
                {
                    test: /\.(png|jpg|gif)$/i,
                    use: [
                        {
                            loader: 'url-loader',
                            options: {
                                outputPath: 'images/',
                                limit: 4 * 1024,
                                name: "[name].[ext]"
                            },
                        },
                    ]
                }
            ]
        },
        // 引入配置
        ...env.development ? require('./config/webpack.development') : require('./config/webpack.production')
    }
}

eslint

cn.eslint.org/

  1. 初始化
node node_modules/eslint/bin/eslint --init
或者
npx eslint --init

// 选择: To check syntax, find problems, and enforce code style 
  1. 配置文件 .eslintrc.js
module.exports = {
	"env": {
		"browser": true,
		"es6": true
	},
	"extends": "eslint:recommended",
	"globals": {
		"Atomics": "readonly",
		"SharedArrayBuffer": "readonly"
	},
	"parserOptions": {
		"ecmaVersion": 2018,
		"sourceType": "module"
	},
	"rules": {
		"indent": [
			"error",
			4
		],
		"linebreak-style": [
			"error",
			"windows"
		],
		"quotes": [
			"error",
			"double"
		],
		"semi": [
			"error",
			"always"
		]
	}
};

stylelint

webpack.js.org/plugins/sty…

  1. webpack.config.js
+ const StyleLintPlugin = require('stylelint-webpack-plugin');
+ module.exports = {
  plugins: [
    new StyleLintPlugin({
        files: ['**/*.css','**/*.scss']
    }),
  ],
}
  1. 添加配置文件
// package.json
{
	+ "stylelint": {
    "extends": "stylelint-config-standard"
  }
}

autoprefixer

配合 postcss-loader 给 css 添加前缀
github.com/browserslis…
browserl.ist/

  1. package.json
{
	+"browserslist": [
    "last 1 version",
    "> 1%",
    "maintained node versions",
    "not dead"
  ]
}

postcss-loader

配合 autoprefixer 给 css 添加前缀
webpack.js.org/loaders/pos…

rules:[
  + {
    loader: "postcss-loader",
    options: {
      plugins: [
        require("autoprefixer")
      ]
    }
  }
]

sass-loader

webpack.js.org/loaders/sas…

rules:[
  + {
    test: /\.scss$/i,
    use: [
      "style-loader",
      "css-loader",
      "sass-loader"
    ]
  }
]

图片类

使用 url-loader

rules:[
  + {
    test: /\.(png|jpg|gif)$/i,
    use: [
      {
        loader: 'url-loader',
        options: {
          outputPath: 'images/',
          limit: 4 * 1024,
          name: "[name].[ext]"
        },
      },
    ]
  }
]

HtmlWebpackPlugin

webpack.js.org/plugins/htm…

+ const HtmlWebpackPlugin = require('html-webpack-plugin');

plugins: [
  + new HtmlWebpackPlugin({
    template: path.resolve('./index.html')
  })
]

更多

1. 在 html 引用图片路径

<img src="${require('./src/images/logo.jpg')}" alt="">

2. 多个文件打包

// webpack.config.js

module.exports = {
  entry: {
    main: [
      './src/js/index1.js',
      './src/js/index2.js',
      './src/js/index3.js',
      './src/js/index4.js',
      './src/js/index5.js'
    ]
  }
}

3. 单独导出css

webpack.docschina.org/plugins/ext…

// 务必安装最新版

npm i -D extract-text-webpack-plugin@next
// webpack.config.js

+ const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    entry: {
        main: [
            './src/js/index.js'
        ]
    },
    module: {
        rules: [
            {
                test: /\.scss/,
                + use: ExtractTextPlugin.extract({ 
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader'],
                    publicPath: '../'
                })
            },
        ],
    },
    plugins: [
        + new ExtractTextPlugin('index.css'),
    ],
};

4. 压缩css

// webpack.production.js

+ const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    plugins: [
        + new OptimizeCssAssetsPlugin({
          assetNameRegExp: /\.css$/g,
          cssProcessor: require('cssnano'),
          cssProcessorPluginOptions: {
            preset: ['default', { discardComments: { removeAll: true } }],
          },
          canPrint: true
        })
    ],
};

5. 生产环境清空dist目录

www.npmjs.com/package/cle…

// webpack.production.js

+ const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    plugins: [
        + new CleanWebpackPlugin(),
    ],
};

6. 图片压缩

github.com/tcoopman/im…

module.exports = {
  module: {
    rules: [
      {
        test: /\.(gif|png|jpe?g|svg)$/i,
        use: [
          'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              disable: false,
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false,
              },
              pngquant: {
                quality: '65-90',
                speed: 4
              },
              gifsicle: {
                interlaced: false,
              },
              webp: {
                quality: 75
              }
            },
          },
        ],
      }
    ],
  },
};

7.多页面打包

  1. 文件

src/index.html
src/2.html
src/js/index.html
src/js/2.html

  1. entry
- entry: './src/js/index.js'

+ entry: {
  index:'./src/js/index.js',
    2:'./src/js/2.js'
},
  1. output
- output: {
    filename: 'bundle.js'
}

+ output: {
    filename: '[name].js'
},
  1. HtmlWebpackPlugin
- new HtmlWebpackPlugin({
  template: path.resolve(__dirname,'../src/index.html'),
})

+ new HtmlWebpackPlugin({
  template: path.resolve(__dirname,'../src/index.html'),
  filename:'index.html',
  chunks:['index']
}),
new HtmlWebpackPlugin({
  template: path.resolve(__dirname,'../src/2.html'),
  filename:'2.html',
  chunks:['2']
})

8.添加注释

webpack.docschina.org/plugins/ban…

9.区分环境

webpack.docschina.org/guides/prod…

"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.product.js"
}

持续学习中...