【问题标题】:Store/retrieve config settings in React project with Typescript使用 Typescript 在 React 项目中存储/检索配置设置
【发布时间】:2018-03-21 13:29:54
【问题描述】:

我目前正在使用React 进行一个项目,我使用Typescript 作为语言。在我的项目中,我安装了Webpack。一切正常,但现在,由于我们要投入生产,我希望有一种简单的方法来存储/检索config settings,例如服务器 URL(通常在开发、测试和生产阶段之间有所不同),但我被卡住了。我尝试通过添加"externals" 键来使用webpack.config.js 文件:

externals: {
  'config': JSON.stringify(process.env.ENV === 'production' ? {
    serviceUrl: "https://prod.myserver.com"
  } : {
    serviceUrl: "http://localhost:8000"
  })
} 

然后尝试从我的tsx 组件文件中引用该文件(考虑到webpack.config.js 位于根文件夹中,而我的组件位于/ClientApp/components 中):

import config from '../../webpack.config.js';

或

import {externals} from '../../webpack.config.js';

但我收到以下错误消息:

'webpack.config.js' 被解析为 '[PROJECT_DIR]/webpack.config.js', 但 '--allowJs' 没有设置。

任何解决方案/替代方案来解决这个问题?谢谢

【问题讨论】:

  • 你试过这个解决方案了吗? If you're using typescript, just rename the file extension to .ts instead of .js. (foo.ts) . Then when you import, do not use the file extension: import ( Foo ) from '../node_modules/foo/foo';(来自coffeenexus in typescript Github issue)

标签: reactjs typescript webpack config


【解决方案1】:

我最喜欢的解决您所描述问题的方法是使用 Webpack 的DefinePlugin:

DefinePlugin 允许您创建可以在编译 时配置的全局常量。这对于允许开发构建和发布构建之间的不同行为很有用。

在您的webpack.config.js 中,您可以创建一个全局常量,您可以像这样在应用程序代码中访问它:

new webpack.DefinePlugin({
    ENVIRONMENT: 'prod'
})

然后,在你的 TypeScript 代码中,你可以像这样访问这个常量:

declare const ENVIRONMENT: 'prod' | 'test' | 'dev' | 'etc...';
if (ENVIRONMENT === 'prod') {
    serverUrl = 'https://example.com';
} else {
    .... 
}

请注意,此方法要求您为每个环境单独构建应用程序。相反,如果您构建应用程序一次,然后将输出部署到多个环境,则可以考虑将这种配置放在一个 JSON 文件中,您可以根据每个环境进行交换。

【讨论】:

  • 感谢您的解决方案。但是,您的最后一句话意味着对于每个环境,我应该更改 ENVIRONMENT 的 webpack.config.js 文件值,然后重新构建,对吗?你会如何定义这样的文件?
  • 您不一定需要一个文件——这在一定程度上取决于您如何触发构建。在我们的应用程序中,我们将命令行参数传递给我们的build 命令,即build --dev。我们可以在 webpack.config.js 文件中访问该值,并适当地更改 ENVIRONMENT 常量的值。
  • 这是否意味着每次我需要为 prod 更改一些配置时,我都需要重新构建整个项目?
【解决方案2】:

import config from '../../webpack.config.js'不应该在应用程序本身中使用,它会导致不良影响(它应该被Webpack使用)并且不会提供必要的导出。

externals: { 'config': ... } 表示不存在的config 模块导出映射到指定值。

它应该像这样使用:

import * as config from 'config';

更传统的方法是 provide environment constant as a global 并在真正的 config.ts 模块中使用它。

【讨论】:

  • 感谢您的回复。我有点困惑,你能举个例子吗?在文档中,他们在配置文件中设置了 process.env.NODE_ENV: JSON.Stringify('production') 然后他们声明“因此,像 process.env.NODE_ENV === 'production' 这样的条件? '[name].[hash].bundle.js' : webpack 配置中的'[name].bundle.js' 不能按预期工作。'
  • 这取决于您如何设置 process.env.NODE_ENV 。文档意味着webpack -p 不会自动将 NODE_ENV 设置为“生产”。您必须像 webpack -p --env production 一样手动执行此操作,请参阅 webpack.js.org/guides/environment-variables 。有关更多详细信息,请参阅github.com/webpack/webpack/issues/2537,它非常广泛。我通常没有这个问题,因为我为 dev 和 prod 使用不同的配置文件,它们不依赖于 NODE_ENV 并手动设置ENV global,类似于另一个答案的建议。
  • 谢谢,你能解释一下你如何为开发和生产使用不同的配置吗?我来自 ASP.NET 背景,我对这种方法更熟悉,即使是出于维护目的,因为每次我需要更改一些配置(例如服务 url)时重新构建整个项目非常不方便
  • @CiccioMiami 我像这里所示使用它们,stackoverflow.com/a/49408284/3731501。一些依赖于环境的部分应该在构建时完成,比如enableProdMode()。如果您希望能够动态更改某些部分,您可以通过 API 请求它们。但一般来说,这就是 Angular 的工作方式。如果要更改单个 HTML 行,则需要重新构建项目。
猜你喜欢
  • 2018-12-11
  • 2020-10-11
  • 2020-10-11
  • 1970-01-01
  • 2012-01-27
  • 2017-06-22
  • 1970-01-01
  • 2021-07-08
  • 2011-03-17
相关资源
最近更新 更多