反应:从外部文件读取配置

时间:2019-08-29 14:20:51

标签: javascript reactjs webpack

我正在尝试实现一种解决方案,用于从我的react应用程序中的某些文件中读取配置...不知道什么是最佳实践,但是我采用了以下方式并尝试实现它:

1)在我的应用程序的根目录下(与webpack.config.js并行) 我创建了一个名为config.dev.json的文件,内容如下:

  

{     “ protocol”:“ http”,     “ host”:“ localhost”,     “端口”:“ 8080”   }

2)到webpack.config.js中添加了我的代码(末尾的TODO部分):

 const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const rtlcss = require('rtlcss');
const webpack = require("webpack");

const useExternalCss =
  process.env.CARBON_REACT_STORYBOOK_USE_EXTERNAL_CSS === 'true';

const useStyleSourceMap =
  process.env.CARBON_REACT_STORYBOOK_USE_STYLE_SOURCEMAP === 'true';

const useRtl = process.env.CARBON_REACT_STORYBOOK_USE_RTL === 'true';

const styleLoaders = [
  {
    loader: 'css-loader',
    options: {
      importLoaders: 2,
      sourceMap: useStyleSourceMap,
    },
  },
  {
    loader: 'postcss-loader',
    options: {
      plugins: () => {
        const autoPrefixer = require('autoprefixer')({
          browsers: ['last 1 version', 'ie >= 11'],
        });
        return !useRtl ? [autoPrefixer] : [autoPrefixer, rtlcss];
      },
      sourceMap: useStyleSourceMap,
    },
  },
  {
    loader: 'sass-loader',
    options: {
      includePaths: [path.resolve(__dirname, '..', 'node_modules')],
      data: `
        $feature-flags: (
          ui-shell: true,
        );
      `,
      sourceMap: useStyleSourceMap,
    },
  },
];

module.exports = (baseConfig, env, defaultConfig) => {
  defaultConfig.devtool = useStyleSourceMap ? 'source-map' : '';
  defaultConfig.optimization = {
    ...defaultConfig.optimization,
    minimizer: [
      new TerserPlugin({
        sourceMap: true,
        terserOptions: {
          mangle: false,
        },
      }),
    ],
  };

  defaultConfig.module.rules.push({
    test: /-story\.jsx?$/,
    loaders: [
      {
        loader: require.resolve('@storybook/addon-storysource/loader'),
        options: {
          prettierConfig: {
            parser: 'babylon',
            printWidth: 80,
            tabWidth: 2,
            bracketSpacing: true,
            trailingComma: 'es5',
            singleQuote: true,
          },
        },
      },
    ],
    enforce: 'pre',
  });

  defaultConfig.module.rules.push({
    test: /\.scss$/,
    sideEffects: true,
    use: [
      { loader: useExternalCss ? MiniCssExtractPlugin.loader : 'style-loader' },
      ...styleLoaders,
    ],
  });

  if (useExternalCss) {
    defaultConfig.plugins.push(
      new MiniCssExtractPlugin({
        filename: '[name].[contenthash].css',
      })
    );
  }

  //TODO
  if (!defaultConfig.resolve) {
    defaultConfig.resolve = {};
  }
  if (!defaultConfig.resolve.alias) {
    defaultConfig.resolve.alias = {};
  }
  defaultConfig.resolve.alias.Config = process.env.NODE_ENV === 'production'
      ? path.resolve('./config.prod.json')
      : path.resolve('./config.dev.json');


  return defaultConfig;
};

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('development'),
        'BASE_URL': JSON.stringify('http://localhost:3000/')
      }
    })
  ],

//   externals: {
//     'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? require('./config.prod.json') : require('./config.dev.json'))
//   }
//
//   // externals: {
//   //   'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? {
//   //     serverUrl: "http://test.com:8080"
//   //   } : {
//   //     serverUrl: "http://localhost:8080"
//   //   })
//   // }
//

}

3)并尝试通过某种方式使用它:

let Config = require('Config')

但是我得到了:

  

./ src / stores / RestService.js   找不到模块:无法在“ C”中解析“ Config”:

4 个答案:

答案 0 :(得分:2)

如果您想在没有webpack的情况下设置配置(例如,使用create-react-app时),这就是我的建议:

创建配置文件夹(或随意命名)并添加配置文件和索引文件:

  • config.dev.json
  • config.prod.json
  • index.js

然后在您的config / index.js文件中:

if (process.env.NODE_ENV === 'development') {
    module.exports = require('./config.dev.json')
} else {
    module.exports = require('./config.prod.json')
}

import config from './config';

一起使用

答案 1 :(得分:1)

为什么不这样使用

  1. 在package.json中
"scripts": {
    "develop": "PORT=8080 HOST=localhost PROTOCOL=http node ."
    "production": "Your config here"
}
  1. 创建一个config / app.js
    const config = process.env
    module.export = {
         port: config.PORT,
         protocol: config.PROTOCOL,
         host: config.HOST,
    }
  1. 在您的Webpack中(实际上,我不知道为什么您必须在Webpack中导入配置并重新导出它。如果您希望您的jsx或js文件能够读取PORT,HOST和LOCALHOST,您可以按照以下步骤操作:直到第2步,您就可以在任何app.js文件中自由获取配置文件)
const config = require('./path/to/config/app.js')

module.exports = {
     externals: {
          config: config,
     }
}

答案 2 :(得分:1)

首先,您需要捆绑软件中的配置文件,它不是外部文件(因此我们只需要删除外部部分)即可。

然后,您需要根据环境(使用resolve.alias使用prod或dev)将配置文件解析为其他文件。

也请注意工作目录,请从项目文件夹运行webpack,或使用context配置选项。

建议的webpack配置(最后相关部分):

module.exports = (baseConfig, env, defaultConfig) => {
  defaultConfig.devtool = useStyleSourceMap ? 'source-map' : '';
  defaultConfig.optimization = {
    ...defaultConfig.optimization,
    minimizer: [
      new TerserPlugin({
        sourceMap: true,
        terserOptions: {
          mangle: false,
        },
      }),
    ],
  };

  defaultConfig.module.rules.push({
    test: /-story\.jsx?$/,
    loaders: [
      {
        loader: require.resolve('@storybook/addon-storysource/loader'),
        options: {
          prettierConfig: {
            parser: 'babylon',
            printWidth: 80,
            tabWidth: 2,
            bracketSpacing: true,
            trailingComma: 'es5',
            singleQuote: true,
          },
        },
      },
    ],
    enforce: 'pre',
  });

  defaultConfig.module.rules.push({
    test: /\.scss$/,
    sideEffects: true,
    use: [
      { loader: useExternalCss ? MiniCssExtractPlugin.loader : 'style-loader' },
      ...styleLoaders,
    ],
  });

  defaultConfig.module.rules.push({
    test: /\.json$/,
    use: [
      { loader: useExternalCss ? MiniCssExtractPlugin.loader : 'style-loader' },
      ...styleLoaders,
    ],
  });


  if (useExternalCss) {
    defaultConfig.plugins.push(
      new MiniCssExtractPlugin({
        filename: '[name].[contenthash].css',
      })
    );
  }
  // ensure resolve alias present in the config
  if (!defaultConfig.resolve) {
      defaultConfig.resolve = {};
  }
  if (!defaultConfig.resolve.alias) {
      defaultConfig.resolve.alias = {};
  }
  // resolve the alias to the right config file according to NODE_ENV
  // you'll have to correctly set <relative path to your config>
  defaultConfig.resolve.alias.Config = process.env.NODE_ENV === 'production'
      ? path.resolve(__dirname, '<relative path to your config>/config.prod.json')
      : path.resolve(__dirname, '<relative path to your config>/config.dev.json');


  return defaultConfig;
};


别忘了删除此内容:

module.exports = {
  externals: {
    'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? require('./config.prod.json') : require('./config.dev.json'))
  }

  // externals: {
  //   'Config': JSON.stringify(process.env.NODE_ENV === 'production' ? {
  //     serverUrl: "http://test.test.com:8080"
  //   } : {
  //     serverUrl: "http://localhost:8080"
  //   })
  // }

}

因为它将阻止webpack捆绑文件。

答案 3 :(得分:0)

您可以使用DefinePlugin这样在webpack中定义设置配置

plugins: [
    new webpack.DefinePlugin({
        'process.env': {
            'NODE_ENV': JSON.stringify('development'),
            'BASE_URL': JSON.stringify('http://localhost:5000/')
        }
    })
],

然后只需使用

process.env.BASE_URL 

process.env.NODE_ENV