webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。在使用 WebPack 前你需要先了解 NodeJS 及 NPM。

基础

在使用 WebPack 之前你需要先安装它(NodeJS 的安装及 NPM 的使用此处不再叙述)。以下是 WebPack 使用必装的内容及命令:

npm i webpack -D      // webpack 主程序
npm i webpack-cli -D      // webpack 命令工具包,不安装无法使用 webpack 命令打包
npm i webpack-dev-server -D      // webpack 开发服务器,用于开发模式下实时打包编译,方便开发

如果你没有安装 webpack-dev-server ,那么只能使用如下命令打包文件,生产环境相较于开发环境会压缩代码使其体积更小。

webpack --entry ./src/main.js -o ./dist --mode development    // 开发环境,不压缩 Version:4.3.1
webpack --entry ./src/main.js -o ./dist --mode production     // 生产环境,会压缩 Version:4.3.1

注意:使用上述命令需全局安装 webpack 及 webpack-cli ,否则会报错:’webpack’ 不是内部或外部命令,也不是可运行的程序

安装 webpack-dev-server 后在 package.json 的 scripts 中配置 “server”: “webpack serve –host 127.0.0.1 –port 1001” 并在项目根目录下新建 webpack.config.js 配置 webpack 选项后,即可通过 npm run server 运行 webpack 开发服务器,实时编译。webpack.config.js 的基本配置结构如下:

// WebPack v5.11.1 常用配置

// 引入 Node.js 的 path 模块
const path = require('path');

// 向外暴露一个配置对象
module.exports = {
    // 配置模式 Mode
    mode: 'development',
    // 入口起点 Entry
    entry: {
        main: path.join(__dirname, './src/main.js'),
    },
    // 输出路径 Output
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
    },
    // 配置插件 Plugins
    plugins: [

    ],
    // 配置加载器 Loaders
    module: {
        rules: [
            
        ]
    },
    // 配置别名 Resolve
    resolve: {
        alias: {
            '@': path.resolve(__dirname, 'src/'),
        }
    }
}

模式(Mode)

mode: "development"|"production"

模式(mode)告诉 webpack 打包时如何优化,目前 webpack 支持 development 与 production 两种模式,不同的模式加载的插件不同。设置 mode 后会将对应的值设置给 process.env.NODE_ENV 。

入口(Entry)

entry: String|Array|Object|Function

入口(entry)用来设置 webpack 从哪个文件开始编译,可以是一个字符串、数组、对象或函数。

// 字符串 String
entry: './app.js'
// 数组 Array
entry: ['./src/js/app.js', './src/js/other.js']
// 对象 Object
entry: {
    home: './home.js',
    shared: ['react', 'react-dom', 'redux', 'react-redux'],
    catalog: {
        import: './catalog.js',
        filename: 'pages/[name][ext]',
    },
    personal: {
        import: './personal.js',      // 入口文件路径
        filename: 'pages/personal.js',    // 输出文件名
        dependOn: 'shared',        // 依赖关系
        chunkLoading: 'jsonp',      // 异步加载,理解 chunk
    }
}
// 函数 Function
entry: () => new Promise((resolve) => resolve(['./demo', './demo2']))

出口(Output)

output: Object

出口(Output)用来设置 webpack 输出到什么位置去以及一些输出时的配置,是一个对象。注意:虽然可以设置多个入口起点,但只能有一个输出配置!

// 对象 Object
output: {
    path: path.join(__dirname, './dist'),   // 输出路径
    filename: 'bundle.js'    // 输出文件名,设为 [name].js 则根据 chunk 模块名输出唯一的名称
},

加载器(Loaders)

webpack 默认只编译 js 或 json 文件,对于其他文件需要通过专门的加载器(Loader)进行处理,加载器从右到左(或从下到上)进行处理。其常用配置如下:

安装

使用加载器(loader)前需要使用 npm 命令安装对应的 Loader ,比如:

npm i style-loader css-loader sass-loader -D

配置

module.rules 中配置各个加载器:

module: {
    rules: [
        {   // SCSS 加载器
            test: /\.scss$/,
            loaders: ['style-loader','css-loader','sass-loader'],
        },
        {    // JS 加载器
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
        },
        {    // 图片加载器
            test: /\.jpg|jpeg|png|gif|bmp$/,
            use: [{
                loader: 'url-loader',
                options:{
                    esModule: false,
                    name: 'images/[name].[ext]',
                    limit: 10 * 1024,
                },
            }],
        },
    ]
}

module.rules 中可以设置多个加载器,每种加载器的配置方式略有不同。

  • test:字符串,设置要处理的文件格式,可使用正则匹配;
  • use:数组,包含多个加载器的详细配置
  • include:字符串或数组,指定 test 处理那些文件或文件夹下的内容
  • exclude:字符串或数组,禁止 test 处理那些文件或文件夹下的内容
  • loader:字符串,指定要使用的单一加载器
  • loaders:数组,指定要使用的多个加载器
    常用的加载器有:
  • style-loader:将 css-loader 打包好的代码以<style>标签的形式插入到 HTML 文件中,不想插入到页面中的话可以考虑使用插件:mini-css-extract-plugin 处理一下
  • css-loader:将 css 文件打包,然后交由 style-loader 处理
  • sass-loader:将 sass 文件打包成 css 文件,然后交由 css-loader 与 style-loader 处理
  • less-loader:将 less 文件打包成 css 文件,然后交由 css-loader 与 style-loader 处理
  • babel-loader:编译 ES 语法的高级语言,然后打包成浏览器可识别的 JS 语言
  • url-loader:将文件编码成 base64 通过 URL 直接打包到文件中,避免过多 HTTP 请求,内嵌 file-loader ,当文件超过 limit 大小时自动调用 file-loader 处理
  • file-loader:修改打包后文件的路径,使之与实际使用路径一致
  • html-loader:注意这个加载器不是用来处理 HTML 的,它是用来处理 HTML 中的 url 图片的
  • vue-loader: 将 vue 文件进行打包处理,提取出其中的逻辑代码 script ,样式代码 style 以及 HTML 模板 template ,再分别将它们交给对应的loader去处理。注意需要配置 plugins !
    更多加载器可访问>>>WebPack Loaders

插件(Plugins)

加载器(Loader)只能处理特定类型的模块,如果需要拓展更多功能,比如包优化、资源管理、注入环境变量等,则需要使用插件(Plugins)。

安装

使用插件(Plugins)之前需要使用 npm 命令安装指定插件,并通过 require() 引入到配置文件中。比如:

npm i html-webpack-plugin -D      \\ 安装 html-webpack-plugin 插件

引入

const HtmlWebpackPlugin = require('html-webpack-plugin');      \\ 引入插件

配置

插件(Plugins)是一个数组,可以通过实例化对应的插件并配置所需的选项引入插件以拓展 webpack 更多的功能。

plugins: [
    new HtmlWebpackPlugin({
        template : path.join(__dirname,'./src/index.html'), 
        filename : 'index.html',
        minify   : { 
            removeComments: true,        // 移除页面中的注释
            collapseWhitespace: true,    // 合并空白字符
            removeAttributeQuotes: true, // 移除属性节点上的引号
        }
    })
],

常用的插件有:

  • html-webpack-plugin:生成一个 HTML 文件(不配置 template 则自动生成一个 HTML 结构的文件,否则根据 template 指向的模板生成 HTML 文件)并自动绑定其他打包好的内容,比如 JS、CSS
  • mini-css-extract-plugin:将 CSS 单独抽离出来形成一个 css 文件
  • optimize-css-assets-webpack-plugin:优化压缩 CSS 资源,使其体积更小
    更多插件可访问>>>WebPack Plugins

解析(Resolve)

解析(Resolve)用于配置并告诉 webpack 如何解析各模块内容,比如我们可以配置将 @ 字符解析为 src/ 路径。

resolve: {
    alias: {
        '@': path.resolve(__dirname, 'src/'),
    }
}

模块(module)

模块(module)用来设置 webpack 如何处理不同的模块,比如上面提到的加载器(Loader)就是在 module.rules 下配置的。

优化(Optimization)

优化(Optimization)用来帮助 webpack 用户自定义一些优化配置选项。

开发服务器(DevServer)

开发服务器(DevServer)里配置的一些内容将会影响 webpack-dev-server 工具的使用。对于开发过程中类似跨域无法发起请求等问题,我们可以通过配置该选项在开发阶段临时解决。

// 配置代理 解决跨域问题
devServer: {
    proxy: {
        '/': {
            target: 'https://api.music.quietguoguo.com/',
            changeOrigin: true,
            secure: true,
        }
    },
}

更多 WebPack 配置问题,建议访问官网查看文档: