2016-10-06 2 views
5

Я использую плагин html-webpack-plugin, чтобы ввести теги <script> в файл шаблона для кусков, которые генерирует веб-пакет. У меня также есть несколько глобальных таблиц стилей, которые я хочу динамически добавлять в раздел <head> моего шаблона HTML. Для этого я также использую html-webpack-plugin следующим образом (в этом случае запись/кусок app).Игнорировать Таблицы стилей Angular2 с ExtractTextPlugin в webpack

module.exports = { 
    entry: { 
     'polyfills': './ts/polyfills.ts', 
     'vendor': './ts/vendor.ts', 
     'app': './ts/app.ts' 
    }, 

    module: { 
     loaders: [ 
      { 
       test: /\.ts$/, 
       loaders: ['ts', 'angular2-template-loader'] 
      }, 
      { 
       test: /\.html$/, 
       loader: 'html-loader' 
      }, 
      { 
       test: /\.css$/, 
       loaders: ['to-string-loader', ExtractTextPlugin.extract('style-loader', 'css-loader')] 
      } 
     ] 
    }, 

    plugins: [ 
     new ExtractTextPlugin('css/[name].[contenthash].css'), 

     new webpack.ProvidePlugin({ 
      bootstrap: 'bootstrap' 
     }), 

     new webpack.optimize.CommonsChunkPlugin({ 
      name: 'app', 
      filename: 'js/[name].[chunkhash].min.js', 
      chunks: ['app'] 
     }), 

     new webpack.optimize.CommonsChunkPlugin({ 
      name: 'vendor', 
      filename: 'js/[name].[chunkhash].min.js', 
      chunks: ['vendor'] 
     }), 

     new webpack.optimize.CommonsChunkPlugin({ 
      name: 'polyfills', 
      filename: 'js/[name].[chunkhash].min.js', 
      chunks: ['polyfills'] 
     }), 

     new HtmlWebpackPlugin({ 
      template: 'my-template.html', 
      filename: 'my-template.html', 
      inject: 'body', 
      hash: false 
     }), 
    ] 
}; 

Ниже app.ts файла, в котором я добавил require заявления для каждой таблицы стилей, которые я хотел бы включить в моем шаблоне (они были слиты в единые таблицы стилей).

require('main.css'); 
require('misc.css'); 

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
import { AppModule } from './app.module'; 

platformBrowserDynamic().bootstrapModule(AppModule); 

По сути, это хорошо работает, но загвоздка в том, что я использую эту конфигурацию для приложения Angular2, который состоит из компонентов, которые могут быть связаны таблицы стилей, как в этом примере.

@Component({ 
    styleUrls: [ 
     'my-stylesheet.css' 
    ] 
}) 
export class MyComponent { ... } 

Создание приложения обычно приводят к тонне HTTP вызовов для этих таблиц стилей для компонентов, поэтому для решения этой проблемы, я вытащил таблицу стилей непосредственно в компоненты с помощью angular2-template-loader. Этот загрузчик работает следующим образом.

angular2-шаблон-загрузчик ищет templateUrl и styleUrls деклараций внутри угловых метаданных 2 компонента и заменяет путь с соответствующим требуют утверждения.

Проблема с этим состоит в том, что помимо двух таблиц стилей, которые добавляются к app.ts EntryPoint, WebPack также включает в себя все таблицы стилей, на который ссылается из моих Angular2 компонентов. Поскольку он проходит через зависимости приложения и находит операторы require, добавленные angular2-template-loader. Это нежелательно, потому что я хочу, чтобы эти таблицы стилей были локальными для компонентов, к которым они принадлежат, т. Е. Быть встроенными в JS.

Поэтому мне нужен путь к только включают таблицы стилей, которые я require непосредственно в моей точки входа, возможно, как-то за исключением таблиц стилей компонентов. Проблема в том, что в обоих случаях файл имеет расширение .css, поэтому они оба проходят тест для extract-text-plugin. Я посмотрел документацию загрузчиков/плагинов, но я не мог найти ничего, что могло бы решить мою проблему.

Так что я хочу, чтобы добавить файл app.[contenthash].css в мой файл шаблона (эта часть работы), но за исключением таблиц стилей, на которые ссылается в своих компонентах Angular2 (входит в комплект из angular2-шаблона-загрузчика).

Как я могу предотвратить включение этих таблиц стилей Angular2 в таблицу стилей, добавленную в мой шаблон HTML?

ответ

5

Допустим, у вас есть следующая структура папок:

enter image description here

Так что все мои компоненты находятся внутри приложения папки.

main.ts

require('main.css'); 
require('misc.css'); 

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
import { AppModule } from './app.module'; 

platformBrowserDynamic().bootstrapModule(AppModule); 

/app/app.component.ts

@Component({ 
    selector: 'my-app', 
    template: `<h1>My Angular 2 App</h1>`, 
    styleUrls: ['my-stylesheet.css'] 
}) 
export class AppComponent {} 

Тогда ваше решение может выглядеть следующим образом:

webpack.config.js

{ 
    test: /\.css$/, 
    exclude: /app\\.+\.css$/, <== add this (exclude all styles from app folder) 
    loaders: ['to-string-loader', ExtractTextPlugin.extract('style-loader', 'css-loader')] 
}, 
{ 
    test: /app\\.+\.css$/, 
    loader: 'raw' <== use raw loader for these files 
} 
+0

А, это выглядит неплохо! Я дам ему вращение как можно скорее и дам вам знать, как это происходит. Благодаря! – Andy0708

+0

Я пытался поиграть с этим, но не смог заставить его работать. Прежде всего, мои файлы CSS расположены в 'public/css', где таблицы стилей для компонентов расположены в' public/css/components/**/*. Css'. Я попытался исключить '/ public \/css \/components /' в первом загрузчике и использовал 'raw' для второго, а также множество различных тестов и исключает различные ошибки. Я не уверен, что я испортил пути/регулярное выражение или что проблема. Если бы вы могли представить пример с указанными выше путями, это было бы действительно потрясающе, потому что я не могу заставить его работать. – Andy0708

+0

Попробуйте '/ public \\ css \\ components /' или '/ css \\ components /' – yurzui

1

Вы можете дать webpack подсказку, чтобы различать файлы CSS с помощью двух отдельных шаблонов имен. Предположим, вы назовете все файлы, которые должны быть включены в angular2-template-loader с суффиксом .tl (сокращение от загрузчика шаблонов, например mycss.tl.css), а другое - с суффиксом .pt (сокращение от платформы, например.main.pt.css), то вы можете написать WebPack конфигурации следующим образом:

module: { 
     loaders: [ 
      { 
       test: /\.ts$/, 
       loaders: ['ts', 'angular2-template-loader'] 
      }, 
      { 
       test: /\.pt\.css$/, 
       loaders: ['to-string-loader', ExtractTextPlugin.extract('style-loader', 'css-loader')] 
      }, 
      { 
       test: /\.tl\.css$/, 
       loaders: ['style-loader', 'css-loader'] 
      } 
     ] 
    } 

Ваш компонент определения тогда выглядит

@Component({ 
    styleUrls: [ 
     'my-stylesheet.tl.css' 
    ] 
}) 
export class MyComponent { ... } 

, тогда как в app.ts вы размещаете

require('main.pt.css'); 
require('misc.pt.css'); 

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 
import { AppModule } from './app.module'; 

platformBrowserDynamic().bootstrapModule(AppModule); 

angular2-шаблонный погрузчик затем все еще обматывает css-пути с помощью вызовов require, но на основе вашей конфигурации вы можете иметь другой набор загрузчиков для файлов css.

+0

Я действительно думал о том, чтобы что-то делать, но это казалось взломом в моем сознании, поэтому я подумал, есть ли лучшее решение там. Я немного поиграю с ним и посмотрю, что я могу придумать. Спасибо за ваш ответ! :-) – Andy0708

0

Для всех, кто заинтересован, мне удалось решить проблему, вдохновленную ответом @ yurzui.

module: { 
    loaders: [ 
     { 
      test: /\.ts$/, 
      loaders: ['ts', 'angular2-template-loader'] 
     }, 
     { 
      test: /\.css$/, 
      exclude: [helpers.root('public', 'css', 'components')], 
      loaders: ['to-string-loader', ExtractTextPlugin.extract('style-loader', 'css-loader')] 
     }, 
     { 
      test: /\.css$/, 
      include: [helpers.root('public', 'css', 'components')], 
      loaders: ['raw-loader'] 
     } 
    ] 
} 

В приведенном выше примере, я использую пользовательский помощник мой, чтобы собрать путь к каталогам. Вы могли бы сделать это как-то иначе, но в любом случае это мой помощник (взятый из документации Angular2).

var path = require('path'); 
var _root = path.resolve(__dirname, '..'); // This file is stored within a webpack subdirectory in my case 

function root(args) { 
    args = Array.prototype.slice.call(arguments, 0); 
    return path.join.apply(path, [_root].concat(args)); 
} 

exports.root = root; 

Чтобы использовать его, просто введите его в настройках своего веб-пакета.

var helpers = require('./helpers'); 

Я надеюсь, что это кому-то поможет.

Смежные вопросы