webpack中的ExtractTextPlugin插件在Angular 2中的应用

3

我有一个关于在Angular中使用webpack的工作配置,使得scss文件被插入到bundle.js中。

{
  test: /\.scss$/,
  use: ['raw-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
}

但是我想要一个包含应用程序中所有scss的单个css文件,因此我正在使用ExtractTextPlugin,就像这样:

{
  test: /\.scss$/,
  use: ExtractTextPlugin.extract({
    fallback: ['raw-loader', 'resolve-url-loader', 'sass-loader?sourceMap'],
    use: ['resolve-url-loader', 'sass-loader?sourceMap']
  })
}

现在,我不使用'raw-loader',因为我知道这些文件不必插入到bundle.js中,但是我在编译时出现了错误。

ERROR in ./~/resolve-url-loader!./~/sass-loader/lib/loader.js?sourceMap!./app/app.component.scss
    Module parse failed: /Users/david/Documents/work/my-angular-seed/node_modules/resolve-url-loader/index.js!/Users/david/Documents/work/my-angular-seed/node_
modules/sass-loader/lib/loader.js?sourceMap!/Users/david/Documents/work/my-angular-seed/app/app.component.scss Unexpected token (1:0)
    You may need an appropriate loader to handle this file type.
    | .app {
    |   border: 1px solid red;
    | }

如果我使用raw-loader,构建过程很顺利,但是加载index.html时会出现错误。

Uncaught Error: Expected 'styles' to be an array of strings.

有人知道如何修复这个问题以及出现此问题的原因吗?谢谢!

编辑

我进行了更多的检查,我认为我知道问题出在哪里,但我不知道如何解决它。

如果我使用以下配置

{
  test: /\.scss$/,
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader', 'sass-loader']
  })
}

app.css已生成,一切正常。但是如果我检查bundle.js,组件已经被转换成了这个样子。

AppComponent = __decorate([
    core_1.Component({
        selector: 'app-root',
        styles: [__webpack_require__(23)],
        template: "\n    <div class=\"app\">\n      Hello!\n    </div>\n  "
    })
], AppComponent);

如果我检查模块23,发现它是空的。

/* 23 */
/***/ (function(module, exports) {

// removed by extract-text-webpack-plugin

/***/ }),

我猜这就是Angular抱怨的问题,因为styles是一个空数组。在这里应该完全删除styles标签,因为CSS被用作外部分离的文件,对吧?有没有什么方法可以解决这个问题?

1个回答

0

在编写 CSS 时,通常使用 css-loader 而不是 raw-loader。当 CSS 无法被提取(如 提取选项 中所述)时,fallback 是用于加载器的。我想不到除了 style-loader 之外的其他用途,它会将 CSS 插入到 <style> 标签中。您在 use 中指定的加载器仍然会在此之前应用,因此使用 raw-loader 实际上没有任何效果。

您可以将 .scss 规则更改为以下常见规则(类似于 提取 Sass 中的示例):

{
  test: /\.scss$/,
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: ['css-loader', 'resolve-url-loader', 'sass-loader?sourceMap']
  })
}

如果您不想将 style-loader 作为回退选项,可以将其省略,如果未提取 CSS,则仍将在捆绑包中,但不会注入到 <style> 标签中,但这可能对您没有帮助。


我仍然收到错误消息 Uncaught Error: Expected 'styles' to be an array of strings. 因此,尽管生成了 app.css,但应用程序仍无法工作。 - David
我更新了我的问题并提供了更多信息;实际上,在最终的bundle.js中使用resolve-url-loader与否并不重要,结果是相同的。 - David
我迷失了。在我的index.html中,我有<link href="app.css" rel="stylesheet"></head>,app.css是一个包含应用程序所有CSS的捆绑包,这不应该足够吗?我知道为了开发,在组件中使用单独的scss文件是有意义的,但是构建之后,如果我已经将所有样式捆绑在一个文件中,并且该文件已在主index.html中导入,那么所有样式导入不应该从组件中删除吗? - David
抱歉,我搞混了,你没有使用 CSS 模块,所以忘记我关于导入它们的说法。你不需要指定任何样式,因为你已经在模板中添加了想要的类。但是你仍然需要导入它(这样 webpack 就知道要处理它),只需:import './app.component.scss'。所以完全不需要加上 styles - Michael Jungo
这对我来说听起来不太对,我不应该修改我的源文件来使用webpack、systemjs或其他任何东西。 - David
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接