我正在使用html-webpack-plugin插件将<script>
标记注入到webpack生成的块的模板文件中。我还有一些全局样式表,我想动态添加到HTML模板的<head>
部分。为此,我也使用html-webpack-plugin如下(在这种情况下,app
条目/块是相关的。)
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-template-loader搜索templateUrl和styleUrls Angular 2 Component元数据中的声明并替换 带有相应require语句的路径。
问题在于,除了添加到app.ts
入口点的两个样式表之外,webpack还包括从我的Angular2组件引用的每个样式表。因为它遍历应用程序的依赖项并找到由angular2-template-loader添加的require
语句。这是不可取的,因为我希望这些样式表对于它们所属的组件是本地的,即在JS中内联。
因此,我需要一种方法 直接在我的入口点中包含我require
的样式表,可能以某种方式排除组件样式表。问题是,在这两种情况下,文件都有.css
扩展名,因此它们都通过了extract-text-plugin
的测试。我看了一下加载器/插件的文档,但我找不到能解决问题的东西。
所以我想要的是将app.[contenthash].css
文件添加到我的模板文件中(这部分有效),但不包括我的Angular2组件中引用的样式表(因为angular2-template而包含) -loader)。
如何防止这些Angular2组件样式表包含在添加到HTML模板的样式表中?
答案 0 :(得分:5)
假设您有以下文件夹结构:
所以我的所有组件都位于 app 文件夹中。
<强> 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
}
答案 1 :(得分: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-template-loader然后仍然使用require
调用包装css路径,但根据您的配置,您可以为css文件设置一组不同的加载器。
答案 2 :(得分: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');
我希望这有助于某人。