最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】ReactJS中Webpack用ExtractTextPlugin后导致css丢失JS中没有加载出来

CSS crifan 4686浏览 0评论

折腾:

【已解决】ReactJS中Webpack打包时分离css

期间,虽然用ExtractTextPlugin等插件,实现了css,less等的分离,但是结果是:

css是单独打包出来了:

但是JS文件中,却没有引用到此处的css了,

然后css样式丢失了,导致文字显示异常,和头像丢失了:

ExtractTextPlugin but css not work

ExtractTextPlugin but js not import css

ExtractTextPlugin webpack not load css

ExtractTextPlugin   作用

No CSS files generated from plugin by using css-loader and sass-loader · Issue #155 · webpack-contrib/extract-text-webpack-plugin

Output CSS to different directory with ExtractTextPlugin · Issue #1022 · webpack/webpack

Getting css output using webpack ExtractTextPlugin – Stack Overflow

Webpack 学习笔记-1-处理CSS

Webpack 使用 ExtractTextPlugin 搭配 autoprefixer 的疑问 – 提问 – React 中文

webpack进阶之插件篇 – 小莫 – SegmentFault

blog/webpack关于样式的处理.md at master · zhengweikeng/blog

Can’t extract multiple .css files from a single .js entry (imported multiple .scss files)? · Issue #428 · webpack-contrib/extract-text-webpack-plugin

javascript – Webpack not loading css – Stack Overflow

Getting css output using webpack ExtractTextPlugin – Stack Overflow

其实这里也提到了,在html中要加上:

    <link rel=”stylesheet” href=”/styles/styles.css”>

Output CSS to different directory with ExtractTextPlugin · Issue #1022 · webpack/webpack

最后是搜:

参考之前的preact-boilerplate的配置文件,研究后,基本搞懂了:

其是在webpack.config.babel.js中配置了:

    new HtmlWebpackPlugin({
      template: ‘./index.ejs’,
      minify: { collapseWhitespace: true }
    }),

从模板index.ejs:

输出了html到了目标文件夹,其中link了css文件,最后结果是:

所以才想到,去搜:

HtmlWebpackPlugin

看到了:

HtmlWebpackPlugin · webpack 中文文档(2.2)

提到了:

“如果你有任何CSS资源在webpack的 output 中,(例如,使用 ExtractTextPlugin提取的CSS)那么这些资源将被包含在HTML head 中,使用<link>标记引用。”

即:

此处用了ExtractTextPlugin后,css被提取到了output路径下后,记得要在html的head中加上引用对应的css的。

所以,此处就是:

去在已有的html文件中,加上对于(由于ExtractTextPlugin提取后输出到目标文件夹中的)css文件的引用:

不过由于此处写了多个ExtractTextPlugin的示例,所以先去还原为单个css的写法:

// import CopyWebpackPlugin from ‘copy-webpack-plugin’;
var CopyWebpackPlugin = require(‘copy-webpack-plugin’);
var path = require(‘path’);
var webpack = require(‘webpack’);
var ExtractTextPlugin = require(‘extract-text-webpack-plugin’);
// const ENV = process.env.NODE_ENV || ‘development’;
var isProd = (process.env.NODE_ENV === ‘production’);
console.log(`process.env.NODE_ENV=${process.env.NODE_ENV}, isProd=${isProd}`);
//process.env.NODE_ENV=development, isProd=false
// 多个提取实例
// new ExtractTextPlugin(“[name].[hash].css”);
// new ExtractTextPlugin(“[name].css”);
// const extractCSS = new ExtractTextPlugin(‘stylesheets/[name].css’);
// const extractLESS = new ExtractTextPlugin(‘stylesheets/[name].less’);
let commonPlugins = [
  // new webpack.ProvidePlugin({
  //   $: ‘jquery’,
  //   ‘window.jQuery’: ‘jquery’,
  //   jQuery: ‘jquery’,
  //   ‘window.$’: ‘jquery’,
  // }),
  new webpack.optimize.CommonsChunkPlugin({
    name: ‘vendor’,
    filename: ‘vendor.bundle.js’
  }),
  // new webpack.HotModuleReplacementPlugin()
  new ExtractTextPlugin(‘styles.css’)
  // extractCSS,
  // extractLESS
];
if (isProd) {
  // Note: current not add UglifyJsPlugin for production for:
  // when webpack -p, it will auto added UglifyJsPlugin, then omit here UglifyJsPlugin settings
  // commonPlugins.push(
  //   new webpack.optimize.UglifyJsPlugin({
  //     minimize: true
  //   })
  // );
  commonPlugins.push(
    new CopyWebpackPlugin([
      { from: ‘./index.html’ },
      { from: ‘src/assets’, to: ‘dist’ },
    ])
  );
}
module.exports = {
  entry: {
    index: ‘./src/index.js’,
    vendor : [
      ‘babel-polyfill’, // Set up an ES6-ish environment
      ‘react-hot-loader/patch’,
      ‘./src/adminlte_app.js’
    ],
  },
  output: {
    path: path.resolve(__dirname, ‘build’),
    filename: ‘[name].js’,
    publicPath: ‘/adminlte/’
  },
  // devtool: isProd ? ‘cheap-module-source-map’ : ‘eval’,
  devtool: isProd ? ‘false’ : ‘eval’,
  devServer: {
    // hot: true,
    contentBase: path.resolve(__dirname, ‘build’),
    publicPath: path.resolve(__dirname, ‘/adminlte/’),
    // publicPath: path.resolve(__dirname, ‘/devServerPublicPath/’),
    compress: true,
    port: 3000,
    historyApiFallback: true
  },
  plugins: commonPlugins,
  module: {
    rules: [
      {
        test: /\.jsx?$/, // 匹配’js’ or ‘jsx’ 后缀的文件类型
        // use: [‘react-hot-loader’, ‘babel-loader’],
        include: path.resolve(__dirname, ‘src’),
        // exclude: /(node_modules|bower_components)/,
        exclude: [
          path.resolve(__dirname, ‘node_modules’),
          path.resolve(__dirname, ‘bower_components’)
        ],
        // use: ‘babel-loader’,
        use: {
          loader: ‘babel-loader’,
          options: {
            presets: [‘env’, ‘stage-0’, ‘react’],
            plugins: [‘transform-runtime’, ‘react-hot-loader/babel’]
          }
        }
      },
      {
        test: /\.css$/,
        // use: [‘style-loader’, ‘css-loader’],
        // use: [
        //   { loader: ‘style-loader’ },
        //   {
        //     loader: ‘css-loader’,
        //     options: {
        //       modules: true
        //     }
        //   }
        // ],
        use: ExtractTextPlugin.extract({
          fallback: ‘style-loader’, // 编译后用什么loader来提取css文件
          use: ‘css-loader’ // 指需要什么样的loader去编译文件,这里由于源文件是.css所以选择css-loader
        }),
        // use: extractCSS.extract([ ‘css-loader’, ‘postcss-loader’ ]),
        // use: extractCSS.extract([
        //   ‘css-loader’,
        //   {
        //     loader: ‘postcss-loader’,
        //     options: {
        //       // plugins: () => [require(‘autoprefixer’)]
        //     }
        //   }
        // ]),
        
        include: path.resolve(__dirname, ‘src’)
      },
      {
        test: /\.less$/,
        use: [
          {
            loader: ‘style-loader’ // creates style nodes from JS strings
          }, {
            loader: ‘css-loader’ // translates CSS into CommonJS
          }, {
            loader: ‘less-loader’ // compiles Less to CSS
          }
        ]
        // test: /\.less$/i,
        // use: extractLESS.extract([ ‘css-loader’, ‘less-loader’ ])
      },
      {
        test: /\.(svg|woff2?|ttf|eot|jpe?g|png|gif)$/i,
        //development use url-loader, production use file-loader
        use :
        // use: isProd ?
        //   {
        //     loader: ‘file-loader’,
        //     query: {
        //       // name: ‘[path][name].[ext]?[md5:hash:base64:6]’
        //       //name: ‘[path][name]_[md5:hash:base64:6].[ext]’
        //       name: ‘[name]_[md5:hash:base64:6].[ext]’
        //     }
        //   } :
          {
            loader: ‘url-loader’,
            query: {
              // inline base64 DataURL for <=2KB images, direct URLs for the rest
              // limit: 4096,
              limit: 2048,
              // name: ‘[name]_[md5:hash:base64:6].[ext]’
              name: ‘dist/img/[name]_[md5:hash:base64:6].[ext]’
              // prefix: ‘/adminlte/’
            }
          }
      }
    ]
  },
  resolve: {
    // you can now import file without suffix
    extensions: [‘*’, ‘.jsx’, ‘.js’, ‘.json’, ‘.less’]
  }
};

npm run build去:

生成单个css:

然后给html中加上css引用:

然后再去调试看看,是否可以正常加载css

的确是可以了:

【总结】

此处之所以是在ExtractTextPlugin提取出css文件后,此处html页面,丢失了样式,没有加载css,是因为:

没有在对应的html中加上引用该(通过ExtractTextPlugin提取生成的)css文件。

解决办法:

去html中加上引用该css:

    <!– link ExtractTextPlugin generated css –>
    <link rel=”stylesheet” href=”styles.css”>

即可。

注:

1.当然,如果后期用了ExtractTextPlugin的多个实例,生成多个css文件后,也要改为html中link引用对应的多个css文件。

2.其他项目中,之所以没有手动去加上link这些css,其实是通过HtmlWebpackPlugin生成对应的html中,或者是在HtmlWebpackPlugin所用到的模版(比如之前的那个index.ejs中)就用类似于:

    <% for (var chunk in htmlWebpackPlugin.files.css) { %>
        <link rel=”preload” href=”<%= htmlWebpackPlugin.files.css[chunk] %>”  as=”style”>
    <% } %>

的代码去引用了css文件了-》所以生成的html中也就自动引用了对应的css文件了。

转载请注明:在路上 » 【已解决】ReactJS中Webpack用ExtractTextPlugin后导致css丢失JS中没有加载出来

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.191 seconds, using 22.16MB memory