Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]:v0.6.4 配置namedExports无效 #6339

Closed
NexxLuo opened this issue Apr 19, 2024 · 17 comments · Fixed by web-infra-dev/rsbuild#1577 or #6376
Closed

[Bug]:v0.6.4 配置namedExports无效 #6339

NexxLuo opened this issue Apr 19, 2024 · 17 comments · Fixed by web-infra-dev/rsbuild#1577 or #6376
Labels
A-css Area: css bug Something isn't working

Comments

@NexxLuo
Copy link

NexxLuo commented Apr 19, 2024

Version

windows
chrome
@rsbuild/core 0.6.4

Details

0.5.9一切运行正常,更新到0.6.4后,node_modules下的less文件均无法使用默认导出(报错Cannot read properties of undefined (reading 'test')) ,test为less文件中的类名;

参照0.6.0的发布文档,通过config.module.parser手动配置namedExports依然无效;

场景:
对node_modules中某一个包的less文件进行cssModule处理;
如codesandbox中的nexx-test-less,包中使用了less文件import styles from "./style.less"

Reproduce link

codesandbox

Reproduce Steps

访问上面的codesandbox库,查看控制台输出信息

@xc2
Copy link
Collaborator

xc2 commented Apr 19, 2024

按理来说,rsbuild 默认设置下 0.5.9 import styles from "style.less" 也只能得到一个空对象,有 styles 但是 styles.testundefined

rsbuild 默认设置下你需要使用 style.module.less 这样的命名格式才能使用 css modules 能力。

另外修改 rspack 配置字段是 tools.rspack

@NexxLuo
Copy link
Author

NexxLuo commented Apr 19, 2024

修改了配置后,codesandbox的确没法复现问题了。本地的less文件是node_modules中的一个依赖(通过cssModules.auto将此依赖包下的所有less文件均做cssModule处理),是否是此原因导致的?

@NexxLuo
Copy link
Author

NexxLuo commented Apr 19, 2024

的确是因为less文件在node_modules中的原因,codesandbox已更新

image
image
image

node_modules中的依赖包源码:

image

image

@chenjiahan
Copy link
Member

代码似乎没提交到 codesandbox:

image

@NexxLuo
Copy link
Author

NexxLuo commented Apr 20, 2024

代码似乎没提交到 codesandbox:

image

重新提交了

@xc2
Copy link
Collaborator

xc2 commented Apr 22, 2024

image

这个代码转的很奇怪,import style from "./style.less" 之后不应该再通过 .default 访问了,应该直接通过 style.test 访问

@NexxLuo
Copy link
Author

NexxLuo commented Apr 23, 2024

使用的是umifather-buildgit地址; 而且namedExports=false不是应该就支持这种形式吗,为何0.5.9是正常的。看需不需要做个兼容,如果不兼容的话,我就改下转译

@xc2
Copy link
Collaborator

xc2 commented Apr 23, 2024

使用的是umifather-buildgit地址; 而且namedExports=false不是应该就支持这种形式吗,为何0.5.9是正常的。看需不需要做个兼容,如果不兼容的话,我就改下转译

不好意思看岔了,这里是 require...确实应该有 .default

我觉得是个 bug。

@chenjiahan 请帮忙转到 rspack 。


Issue

rspack.config.js

module.exports = {
  module: {
    parser: {
      'css/module': { namedExports: false }
    },
    rules: [{ test: /\.css$/, type: 'css/module' }]
  },
}

As per doc, when nameExports is false, both default exports and named exports should be available.

When importing a css module with import statement, it behaves as expected;

import * as S from './style.module.css';
console.log(S); // Module { default: Module {foo: "a"}, foo: "a", __esModule: true }

While importing a css module with require statement, the imported module will be esModule without default field - which is not expected.

const S = require('./style.module.css');
console.log(S); // Module { foo: "a", __esModule: true }
// the `default` field is missing

@chenjiahan chenjiahan transferred this issue from web-infra-dev/rsbuild Apr 23, 2024
@chenjiahan
Copy link
Member

done👌

@xc2 xc2 added bug Something isn't working pending triage The issue/PR is currently untouched. A-css Area: css labels Apr 23, 2024
@ahabhgk
Copy link
Contributor

ahabhgk commented Apr 25, 2024

虽然这里配置了 namedExports: false,并且 node_modules 中的 index.js 也是 import styles from "./styles.less"; 这样引入的,但 node_modules 这个包实际的代码会经过 father-build 打包成如下 cjs:

var _style = _interopRequireDefault(require("./style.less"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

所以实际 Rspack 打包时读到的代码是这份 cjs,Rspack v0.5.9 能够正常工作是因为之前并没有给 css module 添加 __esModule:

v0.5.9 require("./style.less") 的结果:

Object { test: "xxx (hash of the class name)" }

v0.6+ require("./style.less") 的结果:

Object {
  __esModule: true, // <-- 注意这里
  test: "xxx (hash of the class name)",
}

这就导致 _interopRequireDefault 这个函数返回了不同的结果

但实际上 v0.5.9 的行为严格上来说并不正确,v0.6+ 默认添加 __esModule 才是更为常见的行为,webpack experiments.css、style-loader、css-loader、mini-css-extract-plugin loader 都会默认添加这个 __esModule,但 style-loader、css-loader 和 mini-css-extract-plugin loader 提供了 esModule 选项来不添加 __esModule,来兼容 cjs,目前 webpack experiments.css 和 rspack experiments.css 还没有提供该选项

目前有以下方案:

  1. rspack experiments.css 实现 esModule 选项,需要先在 webpack experiments.css 实现,所以花费时间可能会比较久
  2. 使用 rspack.CssExtractPlugin,该插件对齐 mini-css-extract-plugin,并开启 esModule: false
  3. 引这个包的 esm 格式的产物

@xc2 xc2 removed the pending triage The issue/PR is currently untouched. label Apr 25, 2024
@NexxLuo
Copy link
Author

NexxLuo commented Apr 26, 2024

@xc2 rspack.CssExtractPluginrsbuild中该如何使用,只能通过appendPlugins

@chenjiahan
Copy link
Member

Rsbuild 近期会默认切换到 rspack.CssExtractPlugin, PR:web-infra-dev/rsbuild#1577

预计还需要 1~2 周进行测试验证

@xc2
Copy link
Collaborator

xc2 commented Apr 26, 2024

@NexxLuo 如果比较紧急的话可以用 bundlerChain 来临时使用,这里有一个最小的例子:

import { defineConfig } from "@rsbuild/core";

export default defineConfig({
  output: {
    // 临时借用 injectStyle 这个配置项来自动配置 css-loader
    injectStyles: true,
  },
  tools: {
    bundlerChain(chain, { CHAIN_ID }) {
      const coreRequire = require("node:module").createRequire(require.resolve("@rsbuild/core"));
      const { CssExtractRspackPlugin } = require(coreRequire.resolve("@rspack/core"));

      chain.plugin("--css-extract").use(CssExtractRspackPlugin, [{ /* plugin options */ }]);

      for (const styleRuleId of [CHAIN_ID.RULE.CSS, CHAIN_ID.RULE.LESS, CHAIN_ID.RULE.SASS]) {
        const rule = chain.module.rule(styleRuleId);

        rule.uses.delete(CHAIN_ID.USE.STYLE);
        rule.use("--css-extract").loader(CssExtractRspackPlugin.loader).before(CHAIN_ID.USE.CSS);
      }
    },
  },
});

@NexxLuo
Copy link
Author

NexxLuo commented May 14, 2024

0.6.15版本是还没包含这个更改吗

@xc2
Copy link
Collaborator

xc2 commented May 14, 2024

0.6.15版本是还没包含这个更改吗

0.7.0 会包含

@leimonio
Copy link
Contributor

leimonio commented May 22, 2024

I'm testing with latest release candidate v0.7.0-beta.1 and this issue is not resolved for me.

Uncaught TypeError: Cannot read properties of undefined (reading 'offset')
    at eval (eval at 51082 (main.bundle.js:1:489113), <anonymous>:82:96)

where offset is defined as {importedScssModule}.default.offset.

Or is the solution expected to be used along with rspack.CssExtractRspackPlugin ? If so, can you please share an example? Thank you in advance.

@leimonio
Copy link
Contributor

I was able to resolve the issue by setting esModule: false in the generator, as below. Thanks to @hardfist

 module: {
      generator: {
        'css/auto': {
          exportsOnly: true,
          exportsConvention: 'camel-case-only',
          esModule: false,
          localIdentName: isDev ? '[path][name][ext]__[local]' : '[hash]',
        },
        css: {
          exportsOnly: true,
          exportsConvention: 'camel-case-only',
          esModule: false,
        },
        'css/module': {
          exportsOnly: true,
          esModule: false,
          exportsConvention: 'camel-case-only',
          localIdentName: isDev ? '[path][name][ext]__[local]' : '[hash]',
        },
      },
      ...
 }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-css Area: css bug Something isn't working
Projects
None yet
5 participants