webpack基础知识学习(六)--javascript转换

194 阅读1分钟

在我们项目开发中,我们现在会用jsx、ts、es6+等不被浏览器识别的语言或者特性,这时候我们就需要一个工具转换这些特性。这就是我们要用babel的原因,他非常类似postcss插件。
1.安装插件 yarn add babel-loader @babel/core @babel/preset-env --dev
babel-loader也是一个类型平台的插件,他什么事情都做不了,最终转换js的还是babel/corebabel/preset-env。 preset-env意思就是预设,她将会把es6+新特性转换为浏览器兼容的语法。
2.修改webpack.config.js

// webpack.config.js
{
    test: /\.js$/,
    use: [
        {
            loader: 'babel-loader',
            options: {
                presets: ['@babel/preset-env']
            }
        }
    ]
}

重新运行npm run build,发现打包过后的js语法都被转换了。

image.png

3.我们可以修改参数来制定需要兼容的平台,babel-loader的参数优先级高于.browserslistrc的优先级。

// webpack.config.js
// 例如下面我只兼容chrome浏览器94版本,他支持es6+语法
{
    test: /\.js$/,
    use: [
        {
            loader: 'babel-loader',
            options: {
                presets: [
                    [
                        '@babel/preset-env',
                        { targets: 'chrome 94' }
                    ]
                ]
            }
        }
    ]
}

4.我们可以把babel提取成一个配置文件,默认为babel.config.js

// babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            { targets: 'chrome 94' }
        ]
    ]
}
// webpack.config.js
{
    test: /\.js$/,
    use: ['babel-loader']
}

重新运行npm run build,发现效果是一样的。

除了babel做了兼容以外,还需要使用polyfill做补充兼容,比如很老的浏览器不能支持promise,这时候只有preset-env是没办法解决这个问题,所以就有polyfill来干这件事。
安装插件 yarn add core-js regenerator-runtime,因为这个补充代码是要进最终的build生产包的,不能加在开发依赖了。

// babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            { 
                /**
                 * false  不对项目的js做polyfill的处理
                 * usage  依据代码中所使用的带的语法进行填充
                 * entry  依据所要兼容的平台进行填充
                 */
                useBuiltIns: 'usage',
                // 默认使用版本是2,现在已经是3了,不加会报错
                corejs: 3
            }
        ]
    ]
}

如果要使用entry,需要手动引入两个js文件

// src/app.js

import "core-js/stable";
import "regenerator-runtime/runtime";

还有最后一个小问题,就是我们自己写的代码用polyfill处理过了,那node_modules里的包也有可能被polyfill处理,这样就会冲突,所以我们使用balel-loader时要忽略掉对node_modules下文件的处理。

// webpack.config.js

{
    test: /\.js$/,
    exclude: /node_modules/,
    use: ['babel-loader']
}