admin管理员组

文章数量:1313178

I'm trying to implement a solution for reading configurations from some file in my react app... don't know what is the best practice but I adapted the following way and tried implementing it:

1) under the root of my app (in parallel to webpack.config.js) I created a file called: config.dev.json with this content:

{ "protocol" : "http", "host" : "localhost", "port" : "8080" }

2) to webpack.config.js added my code (TODO part at the end):

 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: ":8080"
//   //   } : {
//   //     serverUrl: "http://localhost:8080"
//   //   })
//   // }
//

}

3) and tried to use it from some ponent that way:

let Config = require('Config')

but I'm getting:

./src/stores/RestService.js Module not found: Can't resolve 'Config' in 'C:

I'm trying to implement a solution for reading configurations from some file in my react app... don't know what is the best practice but I adapted the following way and tried implementing it:

1) under the root of my app (in parallel to webpack.config.js) I created a file called: config.dev.json with this content:

{ "protocol" : "http", "host" : "localhost", "port" : "8080" }

2) to webpack.config.js added my code (TODO part at the end):

 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.:8080"
//   //   } : {
//   //     serverUrl: "http://localhost:8080"
//   //   })
//   // }
//

}

3) and tried to use it from some ponent that way:

let Config = require('Config')

but I'm getting:

./src/stores/RestService.js Module not found: Can't resolve 'Config' in 'C:

Share Improve this question edited Sep 1, 2019 at 6:56 zbeedatm asked Aug 29, 2019 at 14:20 zbeedatmzbeedatm 6792 gold badges20 silver badges46 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

If you want to setup configuration without webpack (e.g. when using create-react-app) this is how I'd suggest:

Create config folder (or name it however you want) and add your config files and index file:

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

And then inside your config/index.js file:

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

Use it with import config from './config';

why not use like this

  1. at your package.json
"scripts": {
    "develop": "PORT=8080 HOST=localhost PROTOCOL=http node ."
    "production": "Your config here"
}
  1. create a config/app.js
    const config = process.env
    module.export = {
         port: config.PORT,
         protocol: config.PROTOCOL,
         host: config.HOST,
    }
  1. In your webpack ( actually, i don't know why you have to import config in your webpack and reexport it. if you want your jsx or js files able to read the PORT, HOST, and LOCALHOST, u can just follow until step 2, and u can freely get your config files in any your app.js files )
const config = require('./path/to/config/app.js')

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

First you need the configuration file in your bundle, it's not an external (so we only need to remove the external part).

Then you need the config file to be resolved as a diffrent file depending on the environment (prod or dev, using resolve.alias).

Be carefull of the working directory too, either run webpack from the project's folder, or use the context configuration option.

Suggested webpack config (relevant part in the end):

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;
};


don't forget to remove this:

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.:8080"
  //   } : {
  //     serverUrl: "http://localhost:8080"
  //   })
  // }

}

As it will prevent webpack from bundling the file.

You can use DefinePlugin to define setting config in webpack like this

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

Then simply use

process.env.BASE_URL 

or

process.env.NODE_ENV

本文标签: javascriptReact Read configurations from external fileStack Overflow