Webpack配置多个入口点错误并带有过滤器

时间:2019-11-07 07:39:02

标签: reactjs webpack

我已经使用create-react-app创建了一个React App,并将其弹出以更好地控制构建过程并将其转变为Browser Extension。

如果只有一个输入文件,我的构建可以正常工作,但是现在我正尝试创建2个额外的文件(它们需要与主文件分开,因为它们将是背景文件),我不知道为什么会在构建时出错。我只需要1个文件带有html页面的javascript(反应),其他2个我就需要是javascript文件的扩展功能。

这是Webpack文件中的原始入口点:

entry: [
    // Include an alternative client for WebpackDevServer. A client's job is to
    // connect to WebpackDevServer by a socket and get notified about changes.
    // When you save a file, the client will either apply hot updates (in case
    // of CSS changes), or refresh the page (in case of JS changes). When you
    // make a syntax error, this client will display a syntax error overlay.
    // Note: instead of the default WebpackDevServer client, we use a custom one
    // to bring better experience for Create React App users. You can replace
    // the line below with these two lines if you prefer the stock client:
    // require.resolve('webpack-dev-server/client') + '?/',
    // require.resolve('webpack/hot/dev-server'),
    isEnvDevelopment &&
        require.resolve("react-dev-utils/webpackHotDevClient"),
    // Finally, this is your app's code:
    paths.appIndexJs
    // We include the app code last so that if there is a runtime error during
    // initialization, it doesn't blow up the WebpackDevServer client, and
    // changing JS code would still trigger a refresh.
].filter(Boolean),

为了使系统可以吐出单独的javascript文件,我在其中添加了两个入口点,如下所示:

entry: {
    app: [
        isEnvDevelopment &&
            require.resolve("react-dev-utils/webpackHotDevClient"),
        paths.appIndexJs
    ].filter(Boolean),
    background: [
        isEnvDevelopment &&
            require.resolve("react-dev-utils/webpackHotDevClient"),
        paths.backgroundIndexJs
    ].filter(Boolean),
    content: [
        isEnvDevelopment &&
            require.resolve("react-dev-utils/webpackHotDevClient"),
        paths.contentIndexJs
    ].filter(Boolean)
},

appIndex-backgroundIndex和contentIndex都在路径文件中定义并指向有效目录。

尝试在此上运行npm run build时,我不断收到错误消息:

Cannot read property 'filter' of undefined

并且无法弄清楚这是怎么回事。

我找不到任何有关为何此入口点需要“ .filter(Boolean)”或我可以在何处关闭它的信息,因此在构建时不需要。

我想也许我可以这样建造:

entry: {
    app: paths.appIndexJs,
    background: paths.backgroundIndexJs,
    content: paths.contentIndexJs
},

但是这也会返回相同的错误,并且Canot读取属性'filter'未定义。

出于好奇,我尝试了以下方法,据我了解,这些文件将文件合并在一起:

entry: [
    paths.appIndexJs,
    paths.backgroundIndexJs,
    paths.contentIndexJs
].filter(Boolean),

项目就构建了,但是即使那样,我也看不到两个不同文件中的任何功能。

我从头开始创建了React Apps,我知道多入口点方法可以生成多个文件,但是当使用create-react-app命令创建项目并弹出该项目时,我无法将入口指向按预期工作。

我认为这里的问题不是如何设置条目,而是尝试在没有在输入行上设置“ filter(Boolean)”的情况下进行构建时显示的错误。

我可以从“常规”和弹出的create-react-app中看到的唯一区别是,Webpack的“常规”方式如下所示:

// This has worked in the past when making configs from scratch
module.exports = { 
    entry: {
        app: paths.appIndexJs
        background: paths.backgroundIndexJs
        paths.contentIndexJs
    },

和弹出的create-react-app看起来像这样:

// this is auto generated and unsure if is the reason why it fails to 
module.exports = function(webpackEnv) { 
    const isEnvDevelopment = webpackEnv === "development";
    const isEnvProduction = webpackEnv === "production";

    ......

    return {
        entry: {
            app: [paths.appIndexJs]
            background: [paths.backgroundIndexJs],
            content: [paths.contentIndexJs]
        },

        .....
    };
};

不确定这对入口点是否有影响,但是我看不到其他与此相关的东西。

什么是错误消息过滤器(布尔),如何解决?

1 个答案:

答案 0 :(得分:0)

gitmemory

处找到解决方案

问题出在CRA的ManifestPlugin配置中。假定入口点将被称为main,这是Webpack的默认值:

    // Generate an asset manifest file with the following content:
 // - "files" key: Mapping of all asset filenames to their corresponding
 //   output file so that tools can pick it up without having to parse
 //   `index.html`
 // - "entrypoints" key: Array of files which are included in `index.html`,
 //   can be used to reconstruct the HTML if necessary
 new ManifestPlugin({
   fileName: 'asset-manifest.json',
   publicPath: publicPath,
   generate: (seed, files, entrypoints) => {
     const manifestFiles = files.reduce((manifest, file) => {
       manifest[file.name] = file.path;
       return manifest;
     }, seed);
     const entrypointFiles = entrypoints.main.filter(  // <--- This line here
       fileName => !fileName.endsWith('.map')
     );

     return {
       files: manifestFiles,
       entrypoints: entrypointFiles,
     };
   },
 }),

修复为

 ...
const entrypointFiles = {};
Object.keys(entrypoints).forEach(entrypoint => {
  entrypointFiles[entrypoint] = entrypoints[entrypoint].filter(fileName => !fileName.endsWith('.map'));
});
...