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

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

CSS crifan 4431浏览 0评论

之前调试期间发现,css的style是被webpack生成后放到html中的:

后来看到很多资料后得知,单独把css提取出来,是需要用到单独的插件的。

参考:

less-loader

去试试

ExtractTextPlugin css 作用

ExtractTextPlugin   作用

webpack-contrib/extract-text-webpack-plugin: Extract text from bundle into a file.

webpack中关于样式的处理 · Issue #9 · zhengweikeng/blog

“一般来说需要引入css-loader和style-loader,其中css-loader用于解析,而style-loader则将解析后的样式嵌入js代码。

将require引入的样式嵌入js文件中,有好处也有坏处。好处是减少了请求数,坏处也很明显,就是当你的样式文件很大时,造成编译的js文件也很大。

我们可以使用插件的方式,将样式抽取成独立的文件。使用的插件就是extract-text-webpack-plugin”

但是后续有很多复杂的说法,目前实在是搞不懂,先不理会。

【WEBPACK】分离css单独打包 – 简书

➜  react-hot-boilerplate git:(master) ✗ npm install extract-text-webpack-plugin –save-dev
npm WARN [email protected] requires a peer of webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc but none was installed.
npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed.
added 3 packages in 10.823s

Webpack 学习笔记-1-处理CSS

ExtractTextWebpackPlugin · webpack 中文文档(2.2)

extract-text-webpack-plugin 作用、安装、使用 – ESnail – 博客园

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

提取 CSS 文件 · vue-loader

Webpack2 学习笔记(三): css 文件打包规则的配置使用 – 竹林品雨|zhulinpinyu’s blog

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

目前用:

var ExtractTextPlugin = require("extract-text-webpack-plugin");
new ExtractTextPlugin("styles.css") //将css打包成单独的文件style.css
      {
        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
        }),
        include: path.resolve(__dirname, ‘src’)
      },

试试效果:

对于已有的一个css文件来说,的确起效果了:

输出时就有:

Child extract-text-webpack-plugin ../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/node_modules/extract-text-webpack-plugin/dist ../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/node_modules/css-loader/index.js!../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/src/app.css:
     1 asset
       [0] ./node_modules/css-loader!./src/app.css 548 bytes {0} [built]
       [2] ./src/assets/img/user1-128×128.jpg 79 bytes {0} [built]
        + 1 hidden module

然后最终输出到build的文件夹中也有对应的文件:

然后再去参考:

less-loader

webpack-contrib/extract-text-webpack-plugin: Extract text from bundle into a file.

给less也加上对应的写法:

➜  react-hot-boilerplate git:(master) ✗ npm install –save-dev postcss-loader
npm WARN [email protected] requires a peer of webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc but none was installed.
npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed.
added 19 packages in 11.682s

配置写法:

var ExtractTextPlugin = require("extract-text-webpack-plugin");
// 多个提取实例
//new ExtractTextPlugin("[name].[hash].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
];
module.exports = {
  plugins: commonPlugins,
  module: {
    rules: [
      …
      {
        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’ ]),
        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’ ])
      },
}

然后去build看看效果。

期间:

【已解决】npm WARN [email protected] requires a peer of webpack@1 || 2 but none was installed

但是结果又出现其他错误:

【已解决】Webpack出错:Module build failed: Error: No PostCSS Config found in

结果,更郁闷的来了:

虽然可以正常npm run dev了:

但是,连调试都无法调试了:

http://localhost:3000/

和:

http://localhost:3000/adminlte/

都无法访问了。。。

然后去:

npm run build

➜  react-hot-boilerplate git:(master) ✗ npm run build
> [email protected] prebuild /Users/crifan/dev/dev_root/daryun/Projects/xxxsourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate
> npm run clean
> [email protected] clean /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate
> rm -rf build/ build.zip
> [email protected] build /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate
> cross-env NODE_ENV=production webpack -p –progress –colors
process.env.NODE_ENV=production, isProd=true
Hash: 684ce2244b76de7df4b1
Version: webpack 3.5.4
Time: 23788ms
                               Asset       Size  Chunks                    Chunk Names
               dist/img/boxed-bg.png    43.7 kB          [emitted]
   dist/img/user1-128x128_vykxhX.jpg    2.88 kB          [emitted]
                    vendor.bundle.js     102 kB       1  [emitted]         vendor
               stylesheets/index.css  375 bytes       0  [emitted]         index
                          index.html    2.55 kB          [emitted]
                      dist/.DS_Store    6.15 kB          [emitted]
                dist/img/avatar3.png    9.78 kB          [emitted]
                dist/img/avatar2.png    8.84 kB          [emitted]
                dist/img/avatar5.png    8.01 kB          [emitted]
                 dist/img/avatar.png    8.54 kB          [emitted]
                  dist/img/.DS_Store    6.15 kB          [emitted]
               dist/img/avatar04.png      14 kB          [emitted]
dist/img/credit/american-express.png    2.21 kB          [emitted]
          dist/img/credit/cirrus.png    1.59 kB          [emitted]
               dist/img/boxed-bg.jpg     124 kB          [emitted]
                            index.js    1.12 MB       0  [emitted]  [big]  index
      dist/img/credit/mastercard.png    1.59 kB          [emitted]
          dist/img/credit/paypal.png    2.05 kB          [emitted]
          dist/img/credit/mestro.png    1.59 kB          [emitted]
         dist/img/credit/paypal2.png    1.37 kB          [emitted]
          dist/img/user1-128×128.jpg    2.88 kB          [emitted]
            dist/img/credit/visa.png    1.14 kB          [emitted]
                  dist/img/icons.png    1.15 kB          [emitted]
          dist/img/default-50×50.gif  184 bytes          [emitted]
          dist/img/user4-128×128.jpg    3.48 kB          [emitted]
          dist/img/user2-160×160.jpg    7.07 kB          [emitted]
          dist/img/user3-128×128.jpg    3.51 kB          [emitted]
          dist/img/user5-128×128.jpg    6.45 kB          [emitted]
          dist/img/user8-128×128.jpg    5.06 kB          [emitted]
          dist/img/user6-128×128.jpg    4.34 kB          [emitted]
          dist/img/user7-128×128.jpg    6.43 kB          [emitted]
[166] (webpack)/buildin/global.js 509 bytes {1} [built]
[464] ./src/index.js 590 bytes {0} [built]
[553] ./src/App.js 14.7 kB {0} [built]
[965] ./src/app.css 41 bytes {0} [built]
[966] multi babel-polyfill react-hot-loader/patch ./src/adminlte_app.js 52 bytes {1} [built]
[1175] ./src/adminlte_app.js 22.6 kB {1} [built]
[1177] ./src/assets/img/user1-128×128.jpg 79 bytes [built]
    + 1171 hidden modules
Child extract-text-webpack-plugin ../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/node_modules/extract-text-webpack-plugin/dist ../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/node_modules/css-loader/index.js!../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/node_modules/postcss-loader/lib/index.js!../../../../../../../xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate/src/app.css:
     1 asset
       [0] ./node_modules/css-loader!./node_modules/postcss-loader/lib!./src/app.css 548 bytes {0} [built]
       [2] ./src/assets/img/user1-128×128.jpg 79 bytes {0} [built]
        + 1 hidden module
> [email protected] postbuild /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate
> npm run package
> [email protected] package /Users/crifan/dev/dev_root/daryun/Projects/xxx/sourcecode/web/AdminManagement/reference/react-hot-boilerplate/react-hot-boilerplate
> zip -r build.zip build/
  adding: build/ (stored 0%)
  adding: build/dist/ (stored 0%)
  adding: build/dist/.DS_Store (deflated 93%)
  adding: build/dist/img/ (stored 0%)
  adding: build/dist/img/.DS_Store (deflated 97%)
  adding: build/dist/img/avatar.png (stored 0%)
  adding: build/dist/img/avatar04.png (stored 0%)
  adding: build/dist/img/avatar2.png (stored 0%)
  adding: build/dist/img/avatar3.png (stored 0%)
  adding: build/dist/img/avatar5.png (stored 0%)
  adding: build/dist/img/boxed-bg.jpg (deflated 7%)
  adding: build/dist/img/boxed-bg.png (deflated 0%)
  adding: build/dist/img/credit/ (stored 0%)
  adding: build/dist/img/credit/american-express.png (stored 0%)
  adding: build/dist/img/credit/cirrus.png (stored 0%)
  adding: build/dist/img/credit/mastercard.png (stored 0%)
  adding: build/dist/img/credit/mestro.png (stored 0%)
  adding: build/dist/img/credit/paypal.png (stored 0%)
  adding: build/dist/img/credit/paypal2.png (stored 0%)
  adding: build/dist/img/credit/visa.png (stored 0%)
  adding: build/dist/img/default-50×50.gif (deflated 7%)
  adding: build/dist/img/icons.png (deflated 2%)
  adding: build/dist/img/user1-128×128.jpg (deflated 5%)
  adding: build/dist/img/user1-128x128_vykxhX.jpg (deflated 5%)
  adding: build/dist/img/user2-160×160.jpg (deflated 3%)
  adding: build/dist/img/user3-128×128.jpg (deflated 5%)
  adding: build/dist/img/user4-128×128.jpg (deflated 0%)
  adding: build/dist/img/user5-128×128.jpg (deflated 2%)
  adding: build/dist/img/user6-128×128.jpg (deflated 3%)
  adding: build/dist/img/user7-128×128.jpg (deflated 2%)
  adding: build/dist/img/user8-128×128.jpg (deflated 3%)
  adding: build/index.html (deflated 68%)
  adding: build/index.js (deflated 69%)
  adding: build/stylesheets/ (stored 0%)
  adding: build/stylesheets/index.css (deflated 39%)
  adding: build/vendor.bundle.js (deflated 68%)

之后

再去打开:

http://localhost:3000/

或:

http://localhost:3000/adminlte/

 都还是可以正常调试的。

但是css是丢失了:

所以是:

虽然是把css分离了,结果却丢失了。。。

所以要继续解决:

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

【总结】

至此,也就基本上实现了,通过ExtractTextPlugin插件去从css(甚至less,sass等文件)中提取出来最终的css文件,输出到output.path的文件夹中了。

然后通过确保html中link引用了这些css文件后,就可以正常生效了。

然后附上此处的,单个实例的ExtractTextPlugin的配置:

// 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’]
  }
};

供参考。

至于多实例的ExtractTextPlugin,以后有了更多的css,less等文件后,再继续折腾。

转载请注明:在路上 » 【已解决】ReactJS中Webpack打包时分离css

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.165 seconds, using 22.17MB memory