1.作用

  • webpack 是一个静态模块打包器(module bundler)。它会递归地构建一个依赖关系图(dependency graph), 其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
  • 打包:可以把多个Javascript文件打包成一个文件,减少服务器压力和下载带宽。
  • 转换:把拓展语言(SCSS/ES6)转换成为普通的JavaScript,让浏览器顺利运行。
  • 优化:WebPack具有优化和提升性能的责任。

2.核心概念

  • entry:webpack.config.js中配置entry属性定义入口,入口获取依赖模块
  • output:webpack.config.js中配置output属性定义输出所创建的bundles
  • loader:webpack.config.js中配置module.rules属性中的目标,将非JavaScript文件转化为能够处理的有效模块并进行打包处理
    • test:标识应该转换的文件
    • use:标识使用的loader
  • plugins:
    • 插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量,webpack.config.js中配置plugins属性
    • 多数插件可通过option自定义,也可针对不同目的传入new实例调用require进来的插件
  • mode:通过选择development或production之中的一个,来设置mode参数启用相应模式下的 webpack 内置的优化

3.入口起点

  • 单入口:entry: string|Array,若是数组则多个依赖注入到一个chunk中
  • 多入口:entry: {[entryChunkName: string]: string|Array}
    • 单页面应用:分离应用程序和第三方库入口,应用程序中引用第三方库的部分替换为_ webpack_require _()调用
    • 多页面应用:为不同页面创建html文档,复用入口之间的代码/模块

4.输出

  • 存在多个入口起点,但只指定一个输出配置
  • 最低要求:配置成一个对象
    • filename:输出文件文件名
    • path:输出目录的绝对路径
  • 多个入口起点:使用占位符确保每个文件具有唯一名称filename: ‘[name].js’
  • 高级进阶:
    • 使用CDN:定义publicPath属性设置CDN地址
    • 资源hash:路径末尾写入[hash]

5.loader

module: {
    rules: [
        {
            test: /\.js$/,
            exclude: /node_modules/,
            include: [resolve('src')],
            use: 'Happypack/loader?id=js'
        },
        {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'url-loader',
            options: {
                esModule: false,
                limit: 10000,
                name: utils.assetsPath('img/[name].[hash:7].[ext]')
            }
        }
    ]
}
  • 使用loader的三种方式
    • 配置:webpack.config.js 文件中指定 loader
    • 内联:每个import语句中显示指定loader
    • CLI:在shell命令中指定它们
  • loader特性
    • loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
    • loader 可以是同步的,也可以是异步的。
    • loader 运行在 Node.js 中,并且能够执行任何可能的操作。
    • loader 接收查询参数。用于对 loader 传递配置。
    • loader 也能够使用 options 对象进行配置。
    • 除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。
    • 插件(plugin)可以为 loader 带来更多特性。
    • loader 能够产生额外的任意文件。
  • 典型loader
    • 加载CSS:style-loader和css-loader,含有CSS字符串的< style >插入到html文件的< head >中
    • 加载图片:file-loader,图像被处理添加到output目录中,将原有相对路径替换成output目录中图像的最终路径
    • 加载字体:file-loader
    • 加载数据:JSON文件内置支持,CSV、TSV和XML需要使用 csv-loader 和 xml-loader

6.插件

plugins: [
    new HtmlWebpackPlugin({
        excludeChunks: ['ui-preview'],
        template: './src/main/index.ejs',
        filename: './index.html',
        favicon: './public/favicon/favicon.ico',
        title: version.CONFIG_VERSION_NAME,
        inject: false,
        hash: true,
        mode: devMode //是否是调试模式 'development'
    })
] 
  • 插件HtmlWebpackPlugin:生成新的index.html,内部引入全部生成的bundle文件,将新生成的index.html替换旧的index.html
  • 插件CleanWebpackPlugin:构建前清空dist文件夹中内容,仅存在新构建的文件

7.模块解析

resolve: {
    extensions: ['.js', '.json', '.vue'], 
    modules: [
        resolve('src'),
        resolve('node_modules')
    ],
    alias: {
        '@': path.resolve(__dirname, "../src"),
    }
}
  • 三种文件路径解析
    • 绝对路径:不需要解析
    • 相对路径:当前目录为上下文目录
    • 模块路径:import "module"将在resolve选项中进行搜索
  • extensions:路径指向文件不具备扩展名时作为文件扩展名
  • modules:模块路径解析中在指定目录中查找模块路径
  • alias:module设置别名,根据别名路径查找模块
  • 路径指向文件夹,采取以下步骤找到正确文件:
    • 文件夹包含package.json:resolve.mainFields配置选项中指定的字段匹配package.json 中的第一个这样的字段确定文件路径。
    • 文件夹不包含package.json / package.json中的main字段没有返回有效路径: resolve.mainFiles配置选项中指定的文件名匹配 import/require 目录下的文件名。
    • 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析。
  • Loader解析遵循与文件解析器指定的规则相同的规则。但是resolveLoader配置选项可以用来为Loader提供独立的解析规则

8.manifest

  • runtime :在模块交互时,连接模块所需的加载和解析逻辑。包括浏览器中的已加载模块的连接,以及懒加载模块的执行逻辑。
  • Manifest:当编译器(compiler)开始执行、解析和映射应用程序时,它会保留所有模块的详细要点形成的数据结构
  • 通过使用 manifest 中的数据,runtime 将能够查询模块标识符,检索出背后对应的模块

9.模块热替换

  • 作用:HMR会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面
  • 支持:不同文件的loader内置支持HMR
  • 方式:保留在完全重新加载页面时丢失的应用程序状态,只更新变更内容
  • 步骤:
    • 应用程序代码要求 HMR runtime 检查更新。
    • HMR runtime(异步)下载更新,然后通知应用程序代码。
    • 应用程序代码要求 HMR runtime 应用更新。
    • HMR runtime(同步)应用更新
  • 编译器update:
    • 更新后的 manifest(JSON)
    • 一个或多个更新后的 chunk (JavaScript)
  • HMR:
    • 可选功能:只影响包含HMR代码的模块,描述模块更新后行为
    • 更新冒泡:模块没有HMR处理函数情况下更新冒泡,一个处理函数能够对整个模块树进行更新
  • 启用HMR:
    • 配置devServer:+ hot: true
    • 配置plugins:+ new webpack.HotModuleReplacementPlugin()
    • 修改index.html:+ if (module.hot) { module.hot.accept('', function() {} ) }
  • 通过Node.js API:
const webpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');

const config = require('./webpack.config.js');
const options = {
  contentBase: './dist',
  hot: true,
  host: 'localhost'
};

webpackDevServer.addDevServerEntrypoints(config, options);
const compiler = webpack(config);
const server = new webpackDevServer(compiler, options);

server.listen(5000, 'localhost', () => {
  console.log('dev server listening on port 5000');
});
Logo

前往低代码交流专区

更多推荐