如何部署导入其自己的样式表的ReactJs组件?

时间:2017-10-03 19:51:52

标签: css reactjs webpack

我正在开发一个大型React组件,我想将其导入另一个React应用程序。 (我本可以把它作为一个大应用程序完成,但我决定将这个组件分成一个自己的项目,以便我可以单独关注组件。)它使用自己的样式表,它用"要求('路径/到/样式表[S]的CSS')&#34 ;.

对于开发,我使用webpack-dev-server服务它,它负责加载和预处理这些样式表。我的问题是,我不知道如何部署组件,以便其他应用程序可以包含它,而不会在浏览器遇到需要的调用(路径/到/ stylesheet)时中断。

我发现很多项目使用webpack-dev-server进行开发的例子,但是直接调用babel(或其他预处理器)以便将组件部署到dist /目录,所以这似乎是一种常见的做法。但是如何处理"需要(' path / to / stylesheet。[s] css')"?如果没有webpack及其加载器的依赖,它们都会失败。

理想情况下,我希望能够将webpack用于开发和生产。然后我可以将我的组件部署为完整的包,并且css将包含在代码中。我之前尝试过这个但是没有用。它还有一个缺点,即主应用程序很难覆盖组件中的样式。

我想另一种方法可能是设置我的管道,以便main.scss包含所有其他样式表,并让Sass输出单个style.css文件,消费应用程序必须单独包含。不太优雅,但它更容易覆盖这些样式。

我还在掌握React及其生态系统,所以我很想知道最好的做法是什么,万一有人知道。

1 个答案:

答案 0 :(得分:1)

您需要运行webpack并捆绑所有JS / CSS,以便可以在其他项目中使用它。如果使用正确的加载器,CSS会直接捆绑到您的JS包中。或者,您可以使用不同的加载程序让webpack生成一个很好的style.css文件,将所有需求(/ path / to / css)捆绑到一个文件中。

你需要做三到四个基本的事情(假设webpack @ 3。*):

  1. 使用" externals"在您的webpack配置文件中,以排除package.json依赖项列表中的库。
  2. 使用babel-loader来转换您的javascript(大多数浏览器都支持ES2015)。
  3. 使用' style-loader' css-loader'和' sass-loader'将您的css / scss捆绑到您的webpack js包中。 (这假设您没有使用服务器端反应渲染。这有点棘手。您需要使用同构样式加载器。)
  4. 或者,使用extract-text-webpack-plugin将您的css拉出到一个单独的文件中。 (在下面的例子中注释掉)
  5. 请务必将bundle.js文件作为package.json

    中的入口点

    以下是您尝试执行的操作的一个很好的示例:(此示例适用于服务器端呈现以及浏览器呈现.BABEL_ENV只允许我们在浏览器上使用css文件。)

    const webpack = require('webpack');
    const ExtractTextPlugin = require('extract-text-webpack-plugin');
    
    const env = process.env.NODE_ENV;
    console.log('Environment: ', env)
    module.exports = {
      devtool: 'source-map',
      entry: env == 'production' ? './src/components/index.js' : './src/index.js',
      output: {
        path: env !== 'production' ? require('path').resolve('./dev'): require('path').resolve('./dist'),
        filename: 'bundle.js',
        publicPath: '/',
        library: 'reactPorto',
        libraryTarget: 'umd'
      },
      externals: env == 'production' ? [
        'jquery',
        'react',
        'react-dom',
        'react-bootstrap',
        /^react-bootstrap\/.+$/,
        'classnames',
        'dom-helpers',
        'react-owl-carousel',
        'react-owl-carousel2',
        'uncontrollable',
        'warning',
        'keycode',
        'font-awesome'
      ] : [],
      devServer: {
        inline: true,
        contentBase: './dev',
        staticOptions: { index: 'test.html' },
        historyApiFallback: {
          rewrites:[{ from: /./, to: 'test.html' }],
        },
        hot: true,
      },
      plugins: [
        // new ExtractTextPlugin({
        //   filename: 'style.css',
        //   allChunks: true
        // }),
        new webpack.DefinePlugin({
          'process.env': {
            'NODE_ENV': JSON.stringify(env || 'development'),
            'BABEL_ENV': JSON.stringify(env || 'development')
          }
        }),
        new webpack.optimize.OccurrenceOrderPlugin(),
        ...(env != 'production' ? [new webpack.HotModuleReplacementPlugin()] : []),
        ...(env == 'production' ? [new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false } })] : []),
        new webpack.NoEmitOnErrorsPlugin()
      ],
      module: {
        rules: [
          {
            test: /\.js$/,
            exclude: /node_modules/,
            use: {
              loader: "babel-loader",
              query: {
                presets: [
                  'es2015',
                  'react',
                  'stage-2',
                  ...(env != 'production' ? ['react-hmre'] : [])
                ],
                plugins: []
              }
            }
          },
          {
            test : /(\.css|\.scss)/,
            // exclude: /node_modules/,
            // use : ExtractTextPlugin.extract({
            //   use: [
            //     'isomorphic-style-loader',
            //     {
            //       loader: 'css-loader',
            //       options: {
            //         importLoaders: 1
            //       }
            //     },
            //     'sass-loader'
            //   ]
            // }),
            use: ['iso-morphic-style-loader', 'css-loader', 'sass-loader']
          },
          {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml'},
          {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
          {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
          {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream"},
          {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
          {test: /\.(png|jpg|jpeg)/, loader: 'file-loader' }
        ]
      }
    }