跳到主要内容

devtool

devtool 控制是否生成,以及如何生成 source map。source map的理解: source map 是为了解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术。webpack 可以通过配置自动给我们生成source map文件。

语法


devtool : false | string

配置项如下:

  1. source-map: 结果为原始代码。最好的 soure map 质量。有完整的结果(包含行、列映射),而且从 loaders 生成的 source map 被使用。但是会很慢

    理解

    source-map 的过程为: webpack 转译 --> babel-loader 转译 --> 开发代码 所以,source-map 生成的 .map 文件就是我们开发源码

    devtool : "source-map"
  2. eval-source-map: 结果为原始开发代码。最高的质量和最低的性能。会为每一个模块生成一个单独的 source map 文件进行内联,并使用 eval 执行。

    devtool : "eval-source-map"
  3. cheap-module-eval-source-map: 结果为开发原始代码,更高的质量和更低的性能

    devtool : "cheap-module-eval-source-map"
  4. eval-cheap-source-map: 结果为转换代码。 每个模块被 eval 执行,并且 source map 作为 ewval 的一个 dataurl

    devtool: "eval-cheap-source-map",
  5. eval: 生成代码 每个模块都被 eval 执行,并且存在 @sourceURL, 带 eval 的构建模式能缓存 sourceMap

    devtool : "eval"
  6. cheap-source-map: 结果为转换代码。生成的 source map 只有行映射没有列映射,从 loaders 生成的 source map 没有被使用

    理解

    cheap-source-map 的过程为: webpack 转译 --> babel-loader 转译 所以,cheap-source-map 生成的 .map 文件是 babel-loader 转译后的代码(不是我们开发源码)

    devtool : "cheap-source-map"
  7. cheap-module-source-map: 结果为开发源代码(行内)。生成的 source map 只有行映射没有列映射,从 loaders 生成的 source map 被使用

    理解

    cheap-module-source-map 的过程为: webpack 转译 --> babel-loader 转译 --> 开发源码 所以,cheap-module-source-map 生成的 .map 文件是开发源码

    devtool : "cheap-module-source-map"

配置项 看似很多,其实就是五个关键字 evalsource-mapcheapmoduleinline 的任意组合。

  • eval: 使用 eval 包裹模块代码,缓存 soruce map , 重建性能更高
  • source-map: 产生 .map 文件
  • cheap: 不包含列信息,不包含 loader 的 source map
  • module: 包含 loader 的 source map ,否则无法定义源文件
  • inline: 将 .map 作为 DataURI 嵌入,不单独生成 .map 文件

组合规则: 关键字可以任意组合,但是有顺序要求 [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

最佳实践


开发环境

开发环境 对于 source map 的要求是速度快,调试更友好

  • 速度快的 source map: eval-cheap-source-map
  • 调试更友好的 source map: cheap-module-source-map
  • 折中的选择 source map: eval-source-map

测试环境

测试环境 可以通过 source-map-dev-tool-plugin 来对source map进行生成,进行更细粒度的控制。

  1. webpack.config.js 关闭 devtool

    devtool: false,
  2. webpack.config.js 引入filemanager-webpack-plugin , 将 build 中的.map文件拷贝至maps文件夹中(提前根目录创建 maps 文件夹)

    new FileManagerPlugin({
    events: {
    onEnd: {
    copy: [
    {
    source: './build/*.map',
    destination: Path.resolve(process.cwd(), './maps/'),
    },
    ],
    delete: [
    './build/*.map',
    ],
    },
    },
    }),
  3. webpck.config.js 通过webpack.SourceMapDevToolPlugin 生成 source map

    new webpack.SourceMapDevToolPlugin({
    filename: '[file].map',
    append: `\n//# sourceMappingURL=http://127.0.0.1:8090/[url]`,
    }),
  4. webpack.config.js 完整配置如下:

    const Path = require("path");
    const webpack = require("webpack");
    const FileManagerPlugin = require("filemanager-webpack-plugin");

    module.exports = {
    devtool: false,
    plugins: [
    new webpack.SourceMapDevToolPlugin({
    filename: '[file].map',
    append: `\n//# sourceMappingURL=http://127.0.0.1:8090/[url]`,
    }),
    new FileManagerPlugin({
    events: {
    onEnd: {
    copy: [
    {
    source: './build/*.map',
    destination: Path.resolve(process.cwd(), './maps/'),
    },
    ],
    delete: [
    './build/*.map',
    ],
    },
    },
    }),
    ],
    };
  5. 入口文件测试

    debugger;
    const a = '哈哈';
    console.log(a);

生产环境

生产环境 必须要排除内联的方式,因为我们不仅要隐藏开发原始代码,也要减少文件体积

  • 调试友好的 source map: sourcemap>cheap-source-map/cheap-module-source-map>hidden-source-map>nosources-source-map
  • 速度快的 source map: cheap
  • 折中的 source map: hidden-source-map

生产环境 通过 hidden-source-map 调试的方案:

  1. webpack.config.js 配置 devtoolhidden-source-map

    devtool: "hidden-source-map",
  2. webpack.config.js 引入 filemanager-webpack-plugin , 将 build 文件夹中的map 拷贝至 maps 文件夹 (提前根目录创建 maps 文件夹)

    new FileManagerPlugin({
    events: {
    onEnd: {
    copy: [
    {
    source: './build/*.map',
    destination: Path.resolve(process.cwd(), './maps/'),
    },
    ],
    delete: [
    './build/*.map',
    ],
    },
    },
    })
  3. webpack.config.js 完整配置如下:

    const Path = require("path");
    const webpack = require("webpack");
    const FileManagerPlugin = require("filemanager-webpack-plugin");

    module.exports = {
    devtool: "hidden-source-map",
    plugins: [
    new FileManagerPlugin({
    events: {
    onEnd: {
    copy: [
    {
    source: './build/*.map',
    destination: Path.resolve(process.cwd(), './maps/'),
    },
    ],
    delete: [
    './build/*.map',
    ],
    },
    },
    }),
    ],
    };
  4. 入口文件调试

    debugger;
    const a = '哈哈';
    console.log(a);
  5. 执行yarn build 命令,打包项目,同时会在maps文件夹中生成.map文件

  6. 指向yarn dev 运行项目

  7. 访问页面,并且右键鼠标,选择Add source map , 添加本地服务中的 source map 文件地址

    • 选择打包之后的index.js 文件,右键选择Add source map

      Preview
    • 添加source map url 地址: 我们本地项目服务地址+maps/index.js.map (与webpack.output 配置要一致) ===> http://localhsot:8090/index.js.map

      Preview
    • 点击add后可以看到已经关联成功了

      Preview