解析标记为 Shebang 的 javascript 文件时出现问题

Problem with parsing javascript file marked as Shebang

我有一个 React 应用程序,我想从第三方库导入一个 javascript 文件,但文件标记为 shebang #!/usr/bin/env node.

我发现(例如这里 )我可以通过覆盖 webpack 配置并添加一个新的加载程序 shebang-loader(我也尝试过 shebang-loader2)来加载文件,但是只推荐在 React 应用程序中覆盖 webpack使用 @craco/craco 所以我将它添加到 package.json 并尝试将加载器添加到现有的 webpack-config.js.

我制作了这行代码。文件 craco.config.js:

const throwError = (message) =>
throwUnexpectedConfigError({
    packageName: 'craco',
    githubRepo: 'gsoft-inc/craco',
    message,
    githubIssueQuery: 'webpack',
});
module.exports = {
webpack: {
    configure: (webpackConfig, {paths}) => {

        const shebangLoader =   { test: /node_modules\/npm-groovy-lint\/lib\/groovy-lint.js$/, loader: "shebang-loader" }

        const {isAdded: shebangLoaderIsAdded1} = addAfterLoader(webpackConfig, loaderByName('url-loader'), shebangLoader);
        if (!shebangLoaderIsAdded1) throwError('failed to add shebang-loader');

        return webpackConfig;
    },
},

};

它解决了 shebang 的问题并忽略了 #!/usr/bin/env node 但现在我仍然得到错误

Module parse failed: Unexpected token (14:16)
File was processed with these loaders:
 * ./node_modules/shebang2-loader/index.js
You may need an additional loader to handle the result of these loaders.
| const { getSourceLines, isErrorInLogLevelScope } = require("./utils");
| class NpmGroovyLint {
>     "use strict";
|     options = {}; // NpmGroovyLint options
|     args = []; // Command line arguments

它似乎无法识别 "use strict" 行。 谁能提出一些建议应该是什么问题?

经过几个小时的调查,我终于得出了解决方案。首先,我不得不说,在浏览器中 运行 的类似反应的应用程序中没有使用 NpmGroovyLint 的选项,因为在我解决了上面提到的问题之后,我认为 NpmGroovyLint 使用节点库作为 perf_hooks 而不是在浏览器环境中可用。

但我可以 post 代码来解决我的问题中描述的问题。需要给名为 'plugin-proposal-class-properties' 的 babel-loader 添加一个插件。这是我剪下的 craco 配置。偶尔可以当菜谱用。

const {addAfterLoader, getLoaders, loaderByName, removeLoaders, throwUnexpectedConfigError} = require('@craco/craco');
const throwError = (message) =>
throwUnexpectedConfigError({
    packageName: 'craco',
    githubRepo: 'gsoft-inc/craco',
    message,
    githubIssueQuery: 'webpack',
});
module.exports = {
webpack: {
    configure: (webpackConfig, {paths}) => {
        const {hasFoundAny, matches} = getLoaders(webpackConfig, loaderByName('babel-loader'));
        if (!hasFoundAny) throwError('failed to find babel-loader');

        const {hasRemovedAny, removedCount} = removeLoaders(webpackConfig, loaderByName('babel-loader'));
        if (!hasRemovedAny) throwError('no babel-loader to remove');
        if (removedCount !== 2) throwError('had expected to remove 2 babel loader instances');

        //add plugin proposal class properties to existing babel loader
        const propClassOptions = {...matches[1].loader.options, ...{plugins: ["@babel/plugin-proposal-class-properties"]}};
        const propClassLoader = {...matches[1].loader, ...{options: propClassOptions}};
        const babelLoaderWithPropClassPlugin = {...matches[1], ...{loader: propClassLoader}};

        const shebangLoader = {
            test: /node_modules\/npm-groovy-lint\/lib\/groovy-lint.js$/,
            use: [{loader: 'shebang2-loader'}, {...{loader: require.resolve('babel-loader')}, ...{options: propClassOptions}}]
        }

        const {isAdded: babelLoaderWithPropClassIsAdded} = addAfterLoader(webpackConfig, loaderByName('url-loader'), matches[0].loader);
        if (!babelLoaderWithPropClassIsAdded) throwError('failed to add ts-loader');

        const {isAdded: babelLoaderIsAdded} = addAfterLoader(webpackConfig, loaderByName('babel-loader'), babelLoaderWithPropClassPlugin.loader);
        if (!babelLoaderIsAdded) throwError('failed to add back babel-loader for non-application JS');

        const {isAdded: shebangLoaderIsAdded1} = addAfterLoader(webpackConfig, loaderByName('url-loader'), shebangLoader);
        if (!shebangLoaderIsAdded1) throwError('failed to add shebang-loader');

        return webpackConfig;
    },
},
};