【问题标题】:import css file into es6 returns string instead of object将css文件导入es6返回字符串而不是对象
【发布时间】:2021-12-05 10:16:18
【问题描述】:

TL;DR

我正在将一个 css 文件导入一个打字稿模块,但导入解析为一个字符串而不是一个对象。谁能告诉我为什么我没有得到一个对象??

示例

// preview.ts

import test from './src/assets/test.theme.css';

// also tried this:
// import * as test from './src/assets/test.theme.css';

console.log('typeof test: ', typeof test);
console.log(test);

控制台输出

详细说明

实际上,我正在尝试为我的 Angular12 组件库设置一个Storybook

为了提供各种主题,我想使用@etchteam/storybook-addon-css-variables-theme插件,在其文档中引用了Webpack的内联加载器语法。

import myTheme from '!!style-loader?injectType=lazyStyleTag!css-loader!./assets/my-theme.css';

将此应用到我的代码时,我的浏览器控制台开始抱怨

错误:myTheme.use 不是函数

在我的研究过程中,我认识到导入的样式表不是评估的 javascript 对象,而是作为包含样式加载器生成的源代码的字符串提供的。

我也认识到,此问题并非特定于样式加载器,所有其他加载器也会发生,例如css-loader、raw-loader等

这个问题也与内联加载器语法无关,因为它也显示在一个简约的 webpack 配置中定义的加载器。

环境:

  • 角 12
  • Webpack 5

复制

我已经设置了GIT repo reproducing the issue

自述文件解释了重现和问题。

【问题讨论】:

  • 你为什么要用 Angular 来做这个?
  • 实际上,我正在尝试为我的 Angular 组件库设置一个故事书。我想使用Storybook addon "cssVariablesTheme",它建议使用样式加载器lazyStyleTag 功能在运行时启用和禁用主题。在遵循文档时,我遇到了奇怪的问题。当进一步深入研究这个问题时,我发现它也发生在所描述的简单用例中。顺便说一句:Storybook 根据我的 angular.json 设置动态生成 webpack 配置。
  • 可能是一个简单的导入错误尝试import * as test from './src/assets/test.theme.css'
  • 你试过这个import './style.css'吗?

标签: javascript css angular webpack import


【解决方案1】:

我在 storybook 和这个扩展上遇到了一个非常相似的问题,除了我正在加载 .scss 文件。 我只是调整了解决方案 2 以适应我的 .scss 案例,它就像一个魅力。 我无法使解决方案 1 起作用,但如前所述,这听起来很老套,而在我看来,解决方案 2 更干净。 非常感谢分享这个解决方案,我挣扎了好几个小时。

【讨论】:

【解决方案2】:

我的问题终于解决了!

分析

这里的主要问题是 @angular-devkit/build-angular 包生成的 webpack 配置。我能够通过调试一个新的 angular12 应用程序来分析它(你可以查看它here)。

通过在/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js 处设置断点,函数:generateWebpackConfig(...),我可以在调试器中检查最终的webpackConfig 对象。

相关的rule 如下所示:

这里重要的部分是设置模块类型为asset/source的规则,指示webpack不要评估加载器的结果。

方案概念一:内联加载器

alexander-kait 的帮助和他对this issue 的大力暗示下, 我能够找到覆盖 webpack 模块声明的内联加载器语法:

import Test from 'test.css.webpack[javascript/auto]!=!!!style-loader?injectType=lazyStyleTag!css-loader!./test.css';

console.log(typeof Test); // output: object
console.log(Test); // output: Object { use: () => void, unuse: () => void }
Test.use(); // this should usually be called by a theme switcher...

我不太确定这里的 url 模式,因为它似乎是一个未记录的功能,但我认为它类似于 <query-pattern>.webpack[<module-type>]!=!<loaders><query>

但是,由于这是一个未记录的功能,我不太愿意使用它。

方案概念2:webpackConfig定制

由于我是在故事书上下文中,所以我决定根据storybook documentation 自定义 webpack 配置。

我的解决方案需要设置命名约定(例如*.theme.css)。

// .storybook/main.js

module.exports = {
  webpackFinal: async (config) => {

    // exclude *.theme.css from the *.css ruleset
    config.module.rules.find(rule => '.css'.match(rule.test)).exclude = [ /\.(?:theme\.css)$/i ];

    // add a rule for *.theme.css
    config.module.rules.push({
      test: /\.(?:theme\.css)$/i,
      use: [
        { loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
        'css-loader',
      ],
    });
  },
};

有了这些规则,我现在可以简单地执行以下操作:

// preview.js

import LightTheme from './light.theme.css';
import DarkTheme from './dark.theme.css';

setupThemeSwitcher(LightTheme, DarkTheme);

请注意,setupThemeSwitcher 函数只是用于示例的伪代码。实际上我正在使用@etchteam/storybook-addon-css-variables-theme 插件...

【讨论】:

    【解决方案3】:

    我很抱歉,但我必须恢复我上次的陈述。 @Akxe 的评论没有解决我的问题。 现在我的导入语句 (import * as test from '...') 解析为一个对象,但它仍然不正确。

    我已经设置了GIT Repo to reproduce the issuereadme.md 文件解释了重现和问题。

    看起来 Webpack 没有执行/评估加载程序的返回值。

    顺便说一句。这不仅仅是css-loader的情况。对于 raw-loader、sass-loader、style-loader 等,结果保持不变。

    我的最终目标是将我的主题文件延迟加载到故事书中。 我尝试遵循@etchteam/storybook-addon-css-variables-> theme 的文档。

    【讨论】:

      【解决方案4】:

      我认为您的 Webpack 配置有误。你已经嵌套了 rules 属性,而不是你应该有 use:

      {
          rules: [
            {
              test: /\.css$/i,
              use: ["style-loader", "css-loader"],
            },
          ],
        }
      

      https://webpack.js.org/loaders/css-loader/

      【讨论】:

      • webpack 配置只是一个摘录。我的实际 webpack 配置是由 Storybook 基于我的 angular.json 设置生成的。我的实际问题描述为here,但没有人打扰甚至阅读它......也许我对我的问题不够清楚......;)
      猜你喜欢
      • 2017-07-18
      • 2011-07-29
      • 2012-11-26
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多