【发布时间】: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