1

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

我发现(例如,这里How to Configure Webpack with Shebang Loader to Ignore Hashbang Importing Cesium React Component into Typescript React Component)我可以通过覆盖 webpack 配置并添加新的加载器 shebang-loader 来加载文件(我也尝试过 shebang-loader2)但是仅建议使用 @craco/craco 在 react 应用程序中覆盖 webpack,因此我将其添加到 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

看起来它不识别“使用严格”行。谁能提出一些建议应该是什么问题?

4

1 回答 1

0

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

但我可以发布解决我的问题中描述的问题的代码。需要向 babel-loader 添加一个名为“plugin-proposal-class-properties”的插件。这是我对 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;
    },
},
};
于 2021-08-18T11:16:20.037 回答