2016-10-06 7 views
5

Używam wtyczki html-webpack-plugin do wprowadzania znaczników <script> do pliku szablonu dla fragmentów generowanych przez pakiet Webpack. Mam również kilka globalnych arkuszy stylów, które chcę dynamicznie dodać do sekcji <head> w szablonie HTML. W tym celu używam również wtyczki html-webpack w następujący sposób (wpis/porcja app jest w tym przypadku odpowiedni).Ignoruj ​​arkusze stylów komponentu Angular2 za pomocą ExtractTextPlugin w pakiecie sieci Web

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 
     }), 
    ] 
}; 

Poniżej znajduje się plik app.ts, gdzie dodałem require oświadczenie dla każdego arkusza stylów, które chciałbym umieścić w moim szablonu (są one scalane w jeden arkusz stylów).

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

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

platformBrowserDynamic().bootstrapModule(AppModule); 

Zasadniczo to działa dobrze, ale haczyk jest, że używam tej konfiguracji dla aplikacji Angular2, który składa się z elementów, które mogły być związane stylów, jak w tym przykładzie.

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

Budowanie aplikacji normalnie prowadzić tony połączeń HTTP dla tych stylów dla elementów, tak aby rozwiązać ten problem, mam wyciągnął stylów bezpośrednio do elementów za pomocą angular2-template-loader. Ten program ładujący działa w następujący sposób.

angular2-template-ładowarki szuka templateUrl i styleUrls deklaracje wewnątrz kątowego 2 metadanych komponentu i zastępuje ścieżki z analogicznym wymaga oświadczenia.

Problem polega na tym, że oprócz tych dwóch stylów, które są dodawane do app.ts punkt_wejścia, WebPack obejmuje również każdy arkusz stylów, który odwołuje się od moich Angular2 komponentów. Ponieważ przechodzi przez zależności aplikacji i znajduje instrukcje require dodane przez program ładujący kąt-2-szablon. Jest to niepożądane, ponieważ chcę, aby te arkusze stylów były lokalne dla komponentów, do których należą, tj. Być wbudowane w JS.

Dlatego potrzebuję sposobu, aby tylko dołączyć arkusze stylów, które I require bezpośrednio w moich punktach wejścia, być może przez jakoś wykluczając arkusze stylów komponentów. Problem polega na tym, że w obu przypadkach plik ma rozszerzenie .css, więc oba pomyślnie przejdą test dla extract-text-plugin. Przyjrzałem się dokumentacji ładowarek/wtyczek, ale nie znalazłem niczego, co rozwiązałoby mój problem.

Więc co chcę dodać plik app.[contenthash].css do mojego pliku szablonu (część działa), ale wyłączeniem stylów odwołuje się moich komponentów Angular2 (w komplecie z powodu angular2-template-loader).

Jak mogę zapobiec dołączaniu tych arkuszy stylów Angular2 do arkusza stylów dodawanego do mojego szablonu HTML?

Odpowiedz

5

Powiedzmy, mają następującą strukturę folderów:

enter image description here

Więc wszystkie moje elementy są umieszczone wewnątrz aplikacji folderu.

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 {} 

Wtedy rozwiązanie może wyglądać następująco:

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

Ah, to wygląda całkiem nieźle! Wezmę to jak najszybciej i dam ci znać, jak to działa. Dzięki! – Andy0708

+0

Próbowałem grać z tym, ale nie mogłem go uruchomić. Przede wszystkim moje pliki CSS znajdują się w 'public/css', gdzie arkusze stylów dla komponentów znajdują się w' public/css/components/**/*. Css'. Próbowałem wykluczyć '/ public \/css \/components /' z pierwszego programu ładującego i użyłem 'raw' dla drugiego, wraz z wieloma różnymi testami i wykluczeniami, z różnymi różnymi błędami. Nie jestem pewien, czy mam problem ze ścieżkami/wyrażeń regularnych lub czym jest problem. Gdybyś mógł podać przykład ze wspomnianymi wcześniej ścieżkami, byłoby to naprawdę niesamowite, ponieważ nie potrafię go uruchomić. – Andy0708

+0

Wypróbuj '/ public \\ css \\ components /' lub '/ css \\ components /' – yurzui

1

Możesz podać podpowiedź do webpada, aby odróżnić pliki CSS za pomocą dwóch oddzielnych wzorów nazw. Załóżmy, że wymienisz wszystkie pliki, które powinny być dołączone przez program ładujący szablon-kątowy z przyrostkiem .tl (skrót od programu ładującego szablony, np. mycss.tl.css), a pozostałe z sufiksem .pt (skrót od platformy, np.main.pt.css), to można napisać config WebPACK następująco:

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'] 
      } 
     ] 
    } 

komponentu definicja wtedy wygląda

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

aw app.ts umieścić

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

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

platformBrowserDynamic().bootstrapModule(AppModule); 

angular2-template-ładowarka następnie owija ścieżki css rozmowami require, ale w oparciu o twoją konfigurację możesz mieć inny zestaw ładowarek dla plików css.

+0

Tak naprawdę myślałem o zrobieniu czegoś podobnego, ale wydawało mi się, że to hack w moim umyśle, więc zastanawiałem się, czy istnieje lepsze rozwiązanie. Będę się z tym trochę bawił i zobaczę, co wymyślę. Dziękuję za Twoją odpowiedź! :-) – Andy0708

0

Dla każdego, kto jest zainteresowany, udało mi się rozwiązać problem, zainspirowany odpowiedzią @ 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'] 
     } 
    ] 
} 

W powyższym przykładzie używam własnego pomocnika do złożenia ścieżki do katalogów. Możesz to zrobić jakoś inaczej, ale tutaj jest mój pomocnik (wzięty z dokumentacji 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; 

Aby z niego skorzystać, po prostu wymagaj tego w konfiguracji Webpack.

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

Mam nadzieję, że to pomoże komuś.