【问题标题】:Webpack: ModuleNotFoundError for an unimported moduleWebpack:未导入模块的 ModuleNotFoundError
【发布时间】:2021-09-12 01:38:53
【问题描述】:

问题

我的项目由一个 yarn monorepo 组成,其中在各种包中,有一个 NextJS 应用程序和一个配置包(也与服务器和一个 react-native 应用程序共享)。在配置模块中,如果环境是生产环境,我会导出生产密钥,而如果项目正在开发中,则导出开发密钥。

import { merge } from "lodash";
import { IConfig, RecursivePartial } from "./interfaces";
import { defaultKeys } from "./default.keys";
import { existsSync } from "fs";

const secretKeys: RecursivePartial<IConfig> = (function (env) {
  switch (env) {
    case "production":
      return require("./production.keys").productionKeys;

    default:
      try {
        if (!existsSync("./development.keys")) {
          return require("./production.keys").productionKeys;
        } else {
          return require("./development.keys").developmentKeys;
        }
      } catch (e) {
      }
  }
})(process.env.NODE_ENV);

export const keys = merge(defaultKeys, secretKeys) as IConfig;

当然,开发配置文件包含在 .gitignore 文件中,因此在生产过程中不存在。

这总是完美的(与服务器和移动应用程序一起使用),事实上,如果 development.keys 文件存在,则无需检查 fs 模块(检查我稍后添加的)。

不过,我最近在项目中添加了一个 NextJs 应用程序。我在开发过程中没有遇到任何问题,但是当我尝试在 Heroku 上部署应用程序时遇到了这个错误:

ModuleNotFoundError: Module not found: Error: Can't resolve './development.keys' in '/tmp/build_43d652bc/packages/config/dist/keys'

我做了什么

最初,我认为这是环境变量的问题,并且在生产中错误地需要开发文件。 然而,我后来意识到这不是问题所在。事实上,即使将用于开发的配置文件的导入放在代码的任何地方,即使在返回之后,错误仍然会继续发生。

import { merge } from "lodash";
import { IConfig, RecursivePartial } from "./interfaces";
import { defaultKeys } from "./default.keys";
import { existsSync } from "fs";

const secretKeys: RecursivePartial<IConfig> = (function (env) {
  switch (env) {
    case "production":
      return require("./production.keys").productionKeys;

    default:
      try {
           if (!existsSync("./development.keys")) {
             return require("./production.keys").productionKeys; // <-------
        } else {
          return require("./production.keys").productionKeys; // <-------
        }

        require("./development.keys").developmentKeys;  // <------- This line should not be executed
      } catch (e) {
        return require("./production.keys").productionKeys;
      }
  }
})(process.env.NODE_ENV);

export const keys = merge(defaultKeys, secretKeys) as IConfig;

就好像在构建过程中,nextjs(或者可能是 webpack)控制了所有的导入,而不遵循代码的“流程”。

我希望有人告诉我我错在哪里,因为此刻我被卡住了。谢谢!

更新

感谢this 讨论的想法,我更改了我的文件,现在看起来像这样:

const getConfigPath = (env?: string): string => {
  console.log(env);
  if (env === "production") return "production.keys";
  else return "development.keys";
};

const secretKeys: RecursivePartial<IConfig> = require("./" +
  getConfigPath(process.env.NODE_ENV)).keys;

export const keys = merge(defaultKeys, secretKeys) as IConfig;

但是,现在我遇到了另一个 webpack 错误:

Module parse failed: Unexpected token (2:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import { IConfig, RecursivePartial } from "../interfaces";
> export declare const keys: RecursivePartial<IConfig>;

好像 webpack 无法识别 typescript 生成的声明文件。但是,该错误是新的,我从未遇到过。我相信这是由于链接讨论中指出的 webpack 的行为。

我相信一些帮助,因为我对 webpack 知之甚少

编辑

这是我的 next.config.js:

const path = require("path");

 module.exports = {
    distDir: '../../.next',
    sassOptions: {
        includePaths: [path.join(__dirname, 'styles')],
        prependData: `@import "variables.module.scss";`
    },
    webpack: (config, { isServer }) => {
      if (!isServer) {
        config.resolve.fallback.fs = false;
      }
      return config;
    },
};   

基本上它们是默认配置。我唯一改变的是构建路径,我制作了一个 sass 文件,我暂时添加了一段代码以允许使用 fs 模块,但是正如您在上面看到的,我不使用它更多的。所以我可以把这个配置去掉。

【问题讨论】:

  • 我需要提供更多信息吗?我应该在github上发布问题吗?我真的被困住了。
  • 你有 webpack.config 文件吗?你能检查一下你是否有@babel/preset-typescript 吗?
  • 您好,感谢您的关注。本质上配置模块不使用 webpack,所以它没有配置文件。但是这个模块被导入到我的服务器中,该服务器使用 NestJS 作为 API,最近使用 NextJs 来呈现页面。我认为 NestJS 和 NextJS 都在后台使用 webpack,但是即使在这种情况下,我也没有添加特定的配置,所以它们应该是默认配置。老实说,我不知道 NextJS 是否使用该插件,但我知道 typescript 支持是默认内置的。我在 NextJS 文件夹中找到了 Webpack 配置文件,但它被缩小了。
  • 哦,我明白了,您能在此处提供您的 next.config.js 详细信息吗?
  • 我已经更新了问题。再次感谢@deechris27

标签: javascript node.js heroku webpack next.js


【解决方案1】:

您需要在 next.config.js 中配置 typescript 的加载器

npm install || yarn add awesome-typescript-loader

module.exports = {

    distDir: '../../.next',
    sassOptions: {
        includePaths: [path.join(__dirname, 'styles')],
        prependData: `@import "variables.module.scss";`
    },

    webpack: (config, options) => {

      const { dir, defaultLoaders, isServer } = options;

      if (!isServer) {
        config.resolve.fallback.fs = false;
       }
    
      config.pageExtensions.push(".ts", ".tsx");
    
      config.resolve.extensions.push(".ts", ".tsx");
    
      config.module.rules.push({
        test: /\.tsx?$/,
        include: [dir],
        exclude: /node_modules/,
        use: [
          defaultLoaders.babel,
          {
           loader: "awesome-typescript-loader",,
          },
        ],
     });
    
    return config;
  }
}

【讨论】:

  • 对不起,我花了这么长时间才回答,但我不得不经历一系列的考验和我的错误。我设法运行了您的代码(删除了“config.pageExtensions.push(".ts", ".tsx"); 行),但不幸的是错误没有改变:编译失败。 ../../../config/dist/keys/x/production.keys.d.ts Module parse failed: Unexpected token (2:7) 你可能需要一个合适的加载器来处理这个文件类型,目前没有加载器配置为处理此文件。 |从“../interfaces”导入 { IConfig, RecursivePartial }; > 导出声明 const 键:RecursivePartial; |
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-16
  • 2019-04-12
  • 1970-01-01
  • 2018-10-10
  • 1970-01-01
  • 2018-03-15
  • 2020-05-05
相关资源
最近更新 更多