首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >忽略webpack中带有Angular2的ExtractTextPlugin组件样式表

忽略webpack中带有Angular2的ExtractTextPlugin组件样式表
EN

Stack Overflow用户
提问于 2016-10-06 19:25:03
回答 3查看 2K关注 0票数 5

我使用插件插件将<script>标记插入到webpack生成的块的模板文件中。我也有一些全局样式表,我想动态地添加到我的<head>模板的部分。为此,我还使用html-webpack-插件如下(在本例中,app条目/块是相关的)。

代码语言:javascript
复制
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语句,我希望在模板中包含这些语句(它们将合并到一个样式表中)。

代码语言:javascript
复制
require('main.css');
require('misc.css');

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

platformBrowserDynamic().bootstrapModule(AppModule);

从本质上讲,这很好,但问题是,我正在为一个Angular2应用程序使用此配置,该应用程序由可能有关联样式表的组件组成,如本例所示。

代码语言:javascript
复制
@Component({
    styleUrls: [
        'my-stylesheet.css'
    ]
})
export class MyComponent { ... }

构建应用程序通常会导致对组件的这些样式表进行大量HTTP调用,因此为了解决这个问题,我使用Angular2-模板加载程序将样式表直接拉到组件中。此加载程序的工作方式如下。

Angular2模板加载程序在角2组件元数据中搜索templateUrl和styleUrls声明,并用相应的require语句替换路径。

问题是,除了添加到app.ts入口点的两个样式表之外,webpack还包括从我的Angular2组件中引用的每个样式表。因为它会遍历应用程序的依赖关系,并找到angular2-template-loader添加的require语句。这是不可取的,因为我希望这些样式表对它们所属的组件是本地的,即在JS中内联。

因此,我需要一种只包含我直接在入口点中require的样式表的方法,也许可以通过某种方式排除组件样式表。问题是,在这两种情况下,文件都有.css扩展名,因此它们都通过了extract-text-plugin的测试。我看了一下加载器/插件的文档,但找不到任何解决问题的方法。

因此,我想要的是向我的模板文件中添加一个app.[contenthash].css文件(这个部分有效),但不包括在我的Angular2组件中引用的样式表(因为angular2-template-loader)。

如何防止将这些Angular2组件样式表包含在添加到我的HTML模板中的样式表中?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-09 16:28:24

假设您有以下文件夹结构:

所以我的所有组件都位于app文件夹中。

main.ts

代码语言:javascript
复制
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

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

那么,您的解决方案可能如下所示:

webpack.config.js

代码语言:javascript
复制
{
  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
}
票数 5
EN

Stack Overflow用户

发布于 2016-10-09 15:35:09

您可以给webpack一个提示,通过使用两个单独的名称模式来区分CSS文件。假设您将所有应该由angular2所包含的文件命名为带有后缀.tl (模板加载程序,例如mycss.tl.css)和其他带有后缀.pt (平台,例如main.pt.css)的模板加载程序,那么您可以编写以下webpack配置:

代码语言:javascript
复制
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']
            }
        ]
    }

然后,您的组件定义看起来像

代码语言:javascript
复制
@Component({
    styleUrls: [
        'my-stylesheet.tl.css'
    ]
})
export class MyComponent { ... }

而在app.ts

代码语言:javascript
复制
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文件设置不同的加载器。

票数 1
EN

Stack Overflow用户

发布于 2016-10-16 22:25:19

对任何感兴趣的人来说,我都是从@yurzui的回答中解决了这个问题。

代码语言:javascript
复制
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 2的文档)。

代码语言:javascript
复制
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配置中使用它。

代码语言:javascript
复制
var helpers = require('./helpers');

我希望这能帮上忙。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39904133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档