【问题标题】:ExtractTextPlugin in webpack for Angular 2Angular 2 的 webpack 中的 ExtractTextPlugin
【发布时间】:2017-07-24 04:56:03
【问题描述】:

我有一个使用 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 是一个空数组。我认为应该在这里做的是完全删除样式标签,因为 css 被用作外部分隔文件,对吧?有没有办法解决这个问题?

【问题讨论】:

    标签: angular webpack extract-text-plugin


    【解决方案1】:

    您可以使用css-loader,它通常用于CSS 的raw-loaderfallback 是不提取 CSS 时使用的加载程序(如 extract options 中所述)。我想不出除了style-loader 之外的任何其他用途,它将CSS 插入&lt;style&gt; 标记中。您在use 中指定的加载器在此之前仍然应用,因此使用raw-loader 并不会真正产生任何效果。

    您可以将.scss 规则更改为这个通用规则(类似于Extracting Sass 中的示例):

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

    如果您不希望 style-loader 作为后备选项,您可以将其关闭,如果未提取 CSS 仍将在包中,只是未注入 &lt;style&gt; 标记,但这可能不会帮不了你。

    【讨论】:

    • 我仍然收到错误消息Uncaught Error: Expected 'styles' to be an array of strings.,所以 app.css 已生成,但应用已损坏。
    • 你是如何使用它们的?如果它在@Component 中,则在导入import css from './app.component.scss' 之后将是styles: [css.app, css.other]。这将向其中添加 appother 类。
    • 我用更多信息更新了我的问题;实际上,如果我使用 resolve-url-loader,在最终的 bundle.js 中并不重要,结果是一样的
    • 原始来源是相关的,而不是生成的。无论如何,看起来您正在传递整个导入的 css,这是一个对象,其类映射到每个 css 类的生成哈希名称。并且在模板中使用类名将不起作用,类被替换为哈希(这就是 css 模块的工作方式)
    • 我迷路了。在我的 index.html 中,我有 &lt;link href="app.css" rel="stylesheet"&gt;&lt;/head&gt; 并且 app.css 是包含应用程序中所有 css 的捆绑包,这还不够吗?我知道对于开发来说,为组件拥有单独的 scss 文件是有意义的,但是在构建之后,如果我已经将所有样式捆绑在一个文件中并且该文件被导入到主 index.html 中,那么不应该所有样式从组件中删除导入?
    猜你喜欢
    • 2017-08-22
    • 2017-05-19
    • 1970-01-01
    • 2018-07-11
    • 2017-07-16
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    相关资源
    最近更新 更多