Skip to content

配置source-map

在解析js的过程中,会把高级语法转换为低级语法,然后会去配一些babel相关的内容,

先来安装一下babel的包

  1. babel-loader 转换高级语法的js的loader
  2. @babel/core babel的核心模块,转换的时候就是这个核心模块去调用转换的方法
  3. @babel/preset-env 预设,告诉插件如何转换,转换的规则
shell
yarn add @babel/core@^7.4.5 @babel/preset-env@^7.4.5 babel-loader@^8.0.6 webpack-dev-server@^3.5.1 -D

修改一下配置文件

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'production', // 模式,默认两种模式 production 和 development

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },

    // 入口
    entry: {
        home: './src/index.js', // 入口1 home
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 配置loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    }
                }
            }
        ]
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
        }),
    ],
}

修改一下index.js文件,写一个出错的ES6语法

js
// webpack-dev-2\src\index.js
console.log('home');

class Log {
    constructor() {
        console.lo('这里出错了');
        // 这里故意写错一个语法
        // 打包后,ES6被转换为ES5,然后还压缩了
        // 很不容易找到错误
        // 所以就需要配置source-map
    }
}

let log = new Log()

配置package.json

json
{
  "name": "webpack-dev-2",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "dev": "webpack-dev-server",
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.4.5",
    "@babel/preset-env": "^7.4.5",
    "babel-loader": "^8.0.6",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.32.2",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.5.1"
  }
}

然后我们尝试运行服务 npm run dev

image-20220114163435235

这时候我们故意写的错误就会在控制台打印出来,但是当我们想定位到出错的地方时,发现是一坨代码,根本就看不懂,出错也提示我们了,在bundle.js的第二行出错了,根没说一样。

image-20220114163534322

devtool: 'source-map'

我们肯定需要有一个映射文件,当出错的时候,一点不是打包后的源码,而是源文件,

这时候我们需要告诉webpack,我们需要调试代码,并且需要源码映射。

我们可以增加一个devtool的配置。修改配置文件

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'production', // 模式,默认两种模式 production 和 development

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },

    // 1. source-map 源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错的列和行
    // 特点是 大 而 全,完全独立的
    devtool: 'source-map', // 增加映射文件,帮我们调试线上代码

    // 入口
    entry: {
        home: './src/index.js', // 入口1 home
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 配置loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    }
                }
            }
        ]
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
        }),
    ],
}

修改完之后,我们打包一下看看结果

image-20220114164143788

我们发现,打包的结果确实多了一个map结尾的文件。

再重新跑一下项目看下结果,发现报错变了,不再是以前的那个提示了。

image-20220114164402822

直接定位到了文件出错的地方,然后我们一点击,直接就跳到了源文件的地方

image-20220114164435535

我们看一下再webpack里,确实有源文件

image-20220114164525207

source-map的特点是,大而全,并且是独立的。

eval-source-map

devtool的另外一个选项,我们试一下

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'production', // 模式,默认两种模式 production 和 development

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },

    // 1. source-map 源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错的列和行
    // 特点是 大 而 全,完全独立的
    // devtool: 'source-map', // 增加映射文件,帮我们调试线上代码

    // 2. eval-source-map 不会产生单独的文件,但是可以显示行和列
    // 特点是会把当前打包的源文件,放到打包后的 bundle.js里
    devtool: 'eval-source-map', // 增加映射文件,帮我们调试线上代码

    // 入口
    entry: {
        home: './src/index.js', // 入口1 home
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 配置loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    }
                }
            }
        ]
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
        }),
    ],
}

打包看一下结果,确实没有map文件了,但是bundle.js的变大了,因为把映射文件直接打包到bundle.js里了。

image-20220114165016821

运行一下看下效果,npm run dev

发现也能正常定位到问题的行和列。

image-20220114165341775

image-20220114165410065

cheap-module-source-map

还一个是不会产生列,但是是一个单独的映射文件,简化的source-map

cheap-module-source-map

修改一下配置文件

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'production', // 模式,默认两种模式 production 和 development

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },

    // 1. source-map 源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错的列和行
    // 特点是 大 而 全,完全独立的
    // devtool: 'source-map', // 增加映射文件,帮我们调试线上代码

    // 2. eval-source-map 不会产生单独的文件,但是可以显示行和列
    // 特点是会把当前打包的源文件,放到打包后的 bundle.js里
    // devtool: 'eval-source-map', // 增加映射文件,帮我们调试线上代码

    // 3. cheap-module-source-map 简化的source-map,不会产生列,但是是一个单独的映射文件
    // 用的不是很多,没啥用感觉
    devtool: 'cheap-module-source-map', // 增加映射文件,帮我们调试线上代码

    // 入口
    entry: {
        home: './src/index.js', // 入口1 home
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 配置loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    }
                }
            }
        ]
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
        }),
    ],
}

image-20220114170205509

image-20220114165907127

cheap-module-eval-source-map

不会产生map文件,集成在打包后的文件中,也不会产生列

修改一下配置文件

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'production', // 模式,默认两种模式 production 和 development

    devServer: { // 开发服务器的配置
        port: 3000, // 默认端口是8080,这里可以改
        progress: true, // 打包时候的进度条
        contentBase: './build', // 以哪个文件夹作为服务的根目录 
        open: true, // 服务启动完毕后,直接打开浏览器
        compress: true, // 启动gzip压缩
    },

    // 1. source-map 源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错的列和行
    // 特点是 大 而 全,完全独立的
    // devtool: 'source-map', // 增加映射文件,帮我们调试线上代码

    // 2. eval-source-map 不会产生单独的文件,但是可以显示行和列
    // 特点是会把当前打包的源文件,放到打包后的 bundle.js里
    // devtool: 'eval-source-map', // 增加映射文件,帮我们调试线上代码

    // 3. cheap-module-source-map 简化的source-map,不会产生列,但是是一个单独的映射文件
    // 用的不是很多,没啥用感觉
    // devtool: 'cheap-module-source-map', // 增加映射文件,帮我们调试线上代码

    // 4. cheap-module-eval-source-map 不会产生map文件,集成在打包后的文件中,也不会产生列
    devtool: 'cheap-module-eval-source-map', // 增加映射文件,帮我们调试线上代码

    // 入口
    entry: {
        home: './src/index.js', // 入口1 home
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },

    // 配置loader
    module: {
        rules: [
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                    }
                }
            }
        ]
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'index.html',
        }),
    ],
}

image-20220114170235181

image-20220114170259566

总结

生产环境打包的时候,如果出错了,因为是打包的文件,并且ES6还被转换为ES5,很不容易调试,所以就可以配置一下source-map

可以用来调试线上的代码,建立一个映射文件,直接精准定位到源代码报错处

devtool共有四种模式

  1. source-map 源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错的列和行,特点是 大 而 全,完全独立的
  2. eval-source-map 不会产生单独的文件,但是可以显示行和列,特点是会把当前打包的源文件,放到打包后的 bundle.js里
  3. cheap-module-source-map 简化的source-map,不会产生列,但是是一个单独的映射文件,用的不是很多,没啥用感觉
  4. cheap-module-eval-source-map 不会产生map文件,集成在打包后的文件中,也不会产生列,可以定位到代码大致出错的行处。

参考

https://www.bilibili.com/video/BV1a4411e7Bz?p=13&spm_id_from=pageDriver