css - 如何部署一个导入自己样式表的 ReactJs 组件?

标签 css reactjs webpack

我正在开发一个大型 React 组件,我想将其导入到另一个 React 应用程序中。 (我本可以将其全部作为一个大型应用程序来完成,但我决定将此组件分离到一个单独的元素中,以便我可以单独关注该组件。)它使用自己的样式表,并通过“require('路径/到/样式表。[s]css')”。

为了开发,我使用 webpack-dev-server 来提供它,它负责加载和预处理这些样式表。我的问题是我不知道如何部署该组件,以便当浏览器遇到那些对 require(path/to/stylesheet) 的调用时,另一个应用程序可以包含它而不会中断。

我发现很多元素使用 webpack-dev-server 进行开发的例子,但是直接调用 babel(或其他预处理器)以将组件部署到 dist/目录,所以这似乎是一个常见的例子实践。但是如何处理那些“require('path/to/stylesheet.[s]css')”的调用呢?没有 webpack 和它的加载器可以依赖,它们都会失败。

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

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

我仍在掌握 React 及其生态系统,所以我很想知道这方面的最佳实践是什么,以防有人知道。

最佳答案

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

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

  1. 在您的 webpack 配置文件中使用“externals”来排除 package.json 依赖项列表中的库。
  2. 使用 babel-loader 转译您的 javascript(大多数浏览器都支持 ES2015)。
  3. 使用“style-loader”、“css-loader”和“sass-loader”将您的 css/scss 捆绑到您的 webpack js 包中。 (假设您没有使用服务器端 react 渲染。这有点棘手。您需要使用同构样式加载器。)
  4. 可选地,使用 extract-text-webpack-plugin 将您的 css 提取到一个单独的文件中。 (在下面的例子中被注释掉了)

确保将 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' }
    ]
  }
}

关于css - 如何部署一个导入自己样式表的 ReactJs 组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46552339/

相关文章:

css - 在 Bootstrap 响应式布局中控制环绕和折叠

reactjs - 'docker-compose run app yarn add raven-js'未在npm_modules中安装软件包

javascript - 如何像这些网站一样进行慢速滚动

javascript - 无法用 Jest 模拟模块并测试函数调用

javascript - "Name = undefined"模块解析失败

javascript - Webpack 在 style-loader 和 extract-text-webpack-plugin 之间切换

html - 动态大小的并排 float

html - Css 网格内容溢出

asp.net - asp.net中垂直左侧菜单栏中的图像按钮

reactjs - 如何使用 webpack 压缩设置 Content-Encoding 元数据 header ?