关于babel-core 编译插件的使用,想请教一下这里编译后的代码为何会把index-browser.js 编译进去?

发布于 2022-09-11 14:29:09 字数 4475 浏览 12 评论 0

如题,我想使用babel-core插件实现一个简单的编译es6代码的demo,代码如下:

src/main.js

var babel = require("@babel/core");
let code = `
    let a = 1;
    let b = 2
    let add = (a, b) => {
        return a + b
    } 
    var list = [1, 2, 3, 4, 5];
    for (item of list) {
        add(item, a)
    }
`
var babelOptions = {
    "presets": ["env"]
}
let result = babel.transform(code, babelOptions, function(err, result) {
    console.log('tranform result:', result, err)
});
console.log(result)

此main.js会由webpack进行打包编译,webpack的配置如下:
webpack.config.js

var HtmlWebpackPlugin = require('html-webpack-plugin')
var VueLoaderPlugin = require('vue-loader/lib/plugin');

var path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin')

var rootPath = path.resolve(__dirname, './')
module.exports = {
    entry: {
        main: './src/main.js'
    },
    output: {
        path: rootPath + '/dist/',
        filename: '[name].js?[chunkhash]'
    },
    resolve: {
        extensions: ['.js', '.json', '.less', '.ejs'],
        alias: {
            '@bootstrap': path.resolve(rootPath, './node_modules/bootstrap/dist'),
        }
    },
    node: {
        fs: 'empty'
    },
    plugins: [
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            filename: 'main.html',
            template: './template/index.html',
            inject: 'body',
            hash: false,
            minify: {
                removeComments: true,
                collapseWhitespace: false
            },
            chunksSortMode: 'dependency'
        })
    ],
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /(node_modules|bower_components)/,
            use: {
                loader: 'babel-loader'
            }
        },
        {
            test: /\.vue$/,
            use: ['vue-loader']
        },
        {
            test: /\.ejs$/,
            use: 'ejs-loader'
        },
        {
            test: /\.css$/,
            use: ["style-loader", {loader: 'css-loader', options: {minimize: true}}, 'postcss-loader']
        },
        {
            test: /\.less$/,
            use: ["style-loader", {loader: 'css-loader', options: {minimize: true}}, 'postcss-loader', 'less-loader']
        },
        {
            test: /\.(png|jpg|gif)$/,
            use: 'url-loader?limit=500000'
        },
        {
            test: /\.(ttf|svg|eot|woff|woff2)$/,
            use: ['file-loader']
        }
        ]
    }
}

打包过程一切顺利,奈何当脚本放到浏览器运行后收到错误信息:

Error: Cannot load preset @babel/preset-env relative to / in a browser

经过一番彻查后发现错误信息是这个方法抛出的:
@babel/core/config/files/index-browser.js

function loadPreset(name, dirname) {
  throw new Error(`Cannot load preset ${name} relative to ${dirname} in a browser`);
}

此时的函数调用栈是:

loadPreset (@babel/core/config/files/index-browser.js) // 抛异常
createDescriptor (@babel/core/lib/config/config-descriptors.js)

但是问题就出在这个index-browser.js文件里,查看config-descriptors.js文件源代码后发现,对loadPreset方法的引用是基于require("./files")这部操作

@babel/core/lib/config/config-descriptors.js

    ...
    ...
var _files = require("./files");
    ...
    ...
const resolver = type === "plugin" ? _files.loadPlugin : _files.loadPreset;

显然按照常理应该调用的是@babel/core/config/files/index.js 中暴露出的的loadPreset方法才对。
而通过查看webpack编译后的代码发现,var _files = require("./files")这部操作webpack实际是把@babel/core/config/files/index-browser.js给引入进来了

clipboard.png
为了找到原因,我把@babel/core的package.json查了一下,发现有如下配置项:
@babel/core/package.json

"browser": {
    "./lib/config/files/index.js": "./lib/config/files/index-browser.js",
    "./lib/transform-file.js": "./lib/transform-file-browser.js"
  },

顺带网上搜了一下package.json的browser字段的含义

browser指定该模板供浏览器使用的版本。Browserify这样的浏览器打包工具,通过它就知道该打包那个文件。

可是个人还是十分困惑,自己的main.js是通过webpack进行编译的,编译过程是在node环境中进行的,可怎么就和browser扯上了呢?导致本该导入files/index.js,结果被替换为files/index-browser.js?
为了验证自己的看法我把main.js 单独用node main.js进行运行,发现仍然报这个错误,为什么就会把index-browser给导入进来了呢?

执行node main.js结果:
clipboard.png

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最冷一天 2022-09-18 14:29:09
var babel = require("@babel/core");
require("@babel/preset-env");
let code = `
    let a = 1;
    let b = 2
    let add = (a, b) => {
        return a + b
    } 
    var list = [1, 2, 3, 4, 5];
    for (item of list) {
        add(item, a)
    }
`;
var babelOptions = {
  presets: ["@babel/env"]
};
let result = babel.transform(code, babelOptions, function(err, result) {
  console.log("tranform result:", result, err);
});
console.log(result);

https://codesandbox.io/s/407o...
我这边用上面的代码测试下来是没问题的

┊风居住的梦幻卍 2022-09-18 14:29:09
        var babel = require("@babel/core");
        require("@babel/preset-env");
        babel.transform("{code(){alert(1)}}", {
            presets: ["@babel/preset-env"]
        }, function(err, result) {
          console.log(err, result)
        });

我也是一样,使用babel.transform时候option里presets怎么引都说找不到。

        Cannot load preset @babel/preset-env relative to / in a browser
        
        "@babel/core": "7.10.2",
        "@babel/preset-env": "7.10.0",
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文