CSS не извлекается для общего фрагмента с помощью плагина extract-text-webpack-plugin

Не уверен, что это ошибка или просто моя настройка, я использую CommonsChunkPlugin, чтобы получить отдельный common.js для трех точек входа в моем проекте, и использую плагин extract-text-webpack-plugin для получения файлов css. Мои точки входа: приложение, вход и регистрация. Я могу получить:

app.js
app.vendor.js
login.js
register.js
common.js

Для CSS:

app.css 
register.css
login.css

Кажется, я не могу сгенерировать common.css. Весь css запихивается в один файл app.css.

Мой проект настроен на основе шаблона веб-пакета vuetify: https://github.com/vuetifyjs/webpack-advanced

Вот моя конфигурация:

3 точки входа:

module.exports = {
  entry: {
    app: './src/main.js',
    login: './src/Login/login.js',
    register: './src/Register/register.js'
 },

Плагины — у меня есть HtmlWebpackPlugin для каждой точки входа (показана только одна):

new HtmlWebpackPlugin({
  filename: process.env.NODE_ENV === 'testing'
    ? 'index.html'
    : config.build.index,
  template: 'index.html',
  inject: false,
  hash: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: false,
    minifyJS: true
  },
  chunksSortMode: appChunkOrder
}),

Общие куски:

new webpack.optimize.CommonsChunkPlugin({
  name: 'app.vendor',
  chunks: ['app'],
  minChunks: isVendor,
}),    
new webpack.optimize.CommonsChunkPlugin({
  name: 'login.vendor',
  chunks: ['login'],
  minChunks: isVendor,
}),
new webpack.optimize.CommonsChunkPlugin({
  name: 'register.vendor',
  chunks: ['register'],
  minChunks: isVendor,
}),    
// Extract chunks common to both app and login
new webpack.optimize.CommonsChunkPlugin({
  name: 'common',
  chunks: ['app.vendor', 'login.vendor', 'register.vendor', 'app', 'login', 'register'],
  minChunks: (module, count) => count >= 2 && isVendor(module),
}),

Полный конфиг:

plugins: [
new webpack.DefinePlugin({'process.env': env }),
new webpack.optimize.UglifyJsPlugin({
  compress: {
    warnings: false
  },
  sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
  filename: utils.assetsPath('css/[name].[contenthash].css')
}),
new OptimizeCSSPlugin({
  cssProcessorOptions: {
    safe: true
  }
}),
// generate Html index files for 3 entries:
new HtmlWebpackPlugin({
  filename: process.env.NODE_ENV === 'testing'
    ? 'index.html'
    : config.build.index,
  template: 'index.html',
  inject: false,
  hash: true,
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: false,
    minifyJS: true
  },
  chunksSortMode: appChunkOrder
}),
new HtmlWebpackPlugin({
  filename: process.env.NODE_ENV === 'testing'
    ? 'src/Login/login.html'
    : config.build.login,
  template: 'src/Login/login.html',
  inject: false,
  hash: true,
  minify: false,
  chunksSortMode: loginChunkOrder
}),
new HtmlWebpackPlugin({
  filename: process.env.NODE_ENV === 'testing'
    ? 'src/Register/register.html'
    : config.build.register,
  template: 'src/Register/register.html',
  inject: false,
  hash: true,
  minify: false,
  chunksSortMode: registerChunkOrder
}),    
// Chunks:
new webpack.optimize.CommonsChunkPlugin({
  name: 'app.vendor',
  chunks: ['app'],
  minChunks: isVendor,
}),    
new webpack.optimize.CommonsChunkPlugin({
  name: 'login.vendor',
  chunks: ['login'],
  minChunks: isVendor,
}),
new webpack.optimize.CommonsChunkPlugin({
  name: 'register.vendor',
  chunks: ['register'],
  minChunks: isVendor,
}),    
// Extract chunks common to both app and login
new webpack.optimize.CommonsChunkPlugin({
  name: 'common',
  chunks: ['app.vendor', 'login.vendor', 'register.vendor', 'app', 'login', 'register'],
  minChunks: (module, count) => count >= 2 && isVendor(module),
}),
// copy custom static assets
new CopyWebpackPlugin([
  {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
  }
])

Любая помощь приветствуется!




Ответы (1)


У меня очень похожая установка, и мне удалось заставить ее работать. Для меня самым важным было импортировать общие стили в .js файлов, а не в .scss файлов.

Вот вкратце мой проект:

common/
  main.scss    <-- common styles
app/
  index.js
  main.scss    <-- styles specific for app
admin/
  index.js
  main.scss    <-- styles specific for admin
registration/
  index.js
  main.scss    <-- styles specific for registration
base.html
webpack.config.js

app/index.js:

import '../common/main'   // <-- this did the trick!
import './main'

// some js...

И admin/index.js, и registration/index.js очень похожи.


webpack.config.js (только важные части с использованием синтаксиса ES6):

const entries = {
  app: 'app/index.js',
  admin: 'admin/index.js'
  registration: 'registration/index.js',
};

const commonChunks = [
  'vendor',
  'common',
];

function isVendor(module) {
  if (typeof module.context !== 'string') {
    return false;
  }
  return module.context.indexOf('node_modules') !== -1;
}

export default {
  entry: {...entries},

  // ...

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common',
      filename: '[name].bundle.js',
      minChunks: 2
    }),

    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      filename: '[name].bundle.js',
      chunks: [...Object.keys(entries), 'common'],
      minChunks: function(module) {
        return isVendor(module);
      }
    }),

    new ExtractTextPlugin({
      filename: '[name].bundle.css'
    }),

    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'base.html'),
      filename: 'app.html',
      chunks: [...commonChunks, 'app'],
      chunksSortMode: 'manual'
    }),

    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'base.html'),
      filename: 'admin.html',
      chunks: [...commonChunks, 'admin'],
      chunksSortMode: 'manual'
    }),

    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'base.html'),
      filename: 'registration.html',
      chunks: [...commonChunks, 'registration'],
      chunksSortMode: 'manual'
    })
  ]
};

Мой первоначальный подход состоял в том, чтобы импортировать common/main.scss в другие файлы .scss, например.

app/main.scss:

@import '../common/main'

// styles specific for app

но это не сработало, и я придумал решение выше.

Кроме того, в моем случае требовалось добавление chunksSortMode: 'manual', поскольку HtmlWebpackPlugin иногда включало сценарии в неправильном порядке.

person pawel    schedule 21.10.2017
comment
Большое спасибо за ваш ответ! Я импортирую сторонние пакеты, такие как: import Vuetify from 'vuetify', я не знаю, как в этом случае обрабатываются css-файлы - нужно ли мне импортировать их отдельно? - person JerryH; 23.10.2017
comment
Я надеюсь, что css, который поставляется со сторонними библиотеками, можно отделить. Но я не импортирую их напрямую по имени файла... - person JerryH; 23.10.2017