2016-10-06 30 views
5

我正在使用html-webpack-plugin插件將<script>標籤注入到webpack生成的塊的模板文件中。我還有一些全球樣式表,我想動態添加到我的HTML模板的<head>部分。爲此,我也使用html-webpack-plugin(如下所示)(在這種情況下,app entry/chunk是相關的)。在Webpack中忽略Angular2組件樣式表ExtractTextPlugin

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入口點兩個樣式表的WebPack還包括每一個從我Angular2部件引用樣式表。因爲它經歷了應用程序的依賴關係,並且找到了由angular2-template-loader添加的require語句。這是不可取的,因爲我希望這些樣式表對於它們所屬的組件是本地的,即在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文件。假設您命名了帶有後綴.tl(模板加載程序的簡寫,例如mycss.tl.css)以及帶有後綴.pt(平臺的縮寫,例如,平臺)的angular2-template-loader應包含的所有文件。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模板裝載機然後仍然使用require來調用css路徑,但根據您的配置,您可以爲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; 

要使用它,只需要在您的webpack配置中使用它。

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

我希望這有助於某人。