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

feat: support css default export and named export at same time #6107

Merged
merged 3 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions crates/rspack_plugin_css/src/parser_and_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use rspack_core::{
BoxSource, ConcatSource, MapOptions, RawSource, ReplaceSource, Source, SourceExt, SourceMap,
SourceMapSource, SourceMapSourceOptions,
},
BoxDependency, BuildExtraDataType, BuildMetaExportsType, CssExportsConvention, ErrorSpan,
GenerateContext, LocalIdentName, Module, ModuleType, ParseContext, ParseResult,
ParserAndGenerator, SourceType, TemplateContext,
BoxDependency, BuildExtraDataType, BuildMetaDefaultObject, BuildMetaExportsType,
CssExportsConvention, ErrorSpan, GenerateContext, LocalIdentName, Module, ModuleType,
ParseContext, ParseResult, ParserAndGenerator, SourceType, TemplateContext,
};
use rspack_core::{ModuleInitFragments, RuntimeGlobals};
use rspack_error::{IntoTWithDiagnosticArray, Result, TWithDiagnosticArray};
Expand Down Expand Up @@ -95,8 +95,11 @@ impl ParserAndGenerator for CssParserAndGenerator {
} else {
BuildMetaExportsType::Default
};

// build_meta.exports_type = BuildMetaExportsType::Namespace;
build_meta.default_object = if self.named_exports {
BuildMetaDefaultObject::False
} else {
BuildMetaDefaultObject::Redirect
};

let swc_compiler = SwcCssCompiler::default();

Expand Down
4 changes: 2 additions & 2 deletions packages/rspack/src/config/normalization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ const getNormalizedEntryStatic = (entry: EntryStatic) => {
dependOn: Array.isArray(value.dependOn)
? value.dependOn
: value.dependOn
? [value.dependOn]
: undefined
? [value.dependOn]
: undefined
};
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as style1 from "./style.module.css?namespace";
import style2 from "./style.module.css?default";
import { foo } from "./style.module.css?named";

it("should able to import with default and named exports", () => {
expect(style1.default).toEqual(nsObj({ foo: '-__style_module_css_namespace-foo' }));
expect(style1.foo).toEqual("-__style_module_css_namespace-foo");
expect(style2).toEqual(nsObj({ foo: '-__style_module_css_default-foo' }));
expect(foo).toEqual("-__style_module_css_named-foo");
});

it("should able to import with different default and namex dynamic export", (done) => {
import("./style.module.css?namespace").then((style1) => {
expect(style1.default).toEqual(nsObj({ foo: '-__style_module_css_namespace-foo' }));
expect(style1.foo).toEqual('-__style_module_css_namespace-foo');

done();
}, done)
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.foo {
color: red;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
target: "node",
mode: "development",
devtool: false,
module: {
rules: [
{
test: /\.css/,
parser: {
namedExports: false
},
type: "css/module"
}
]
},
experiments: {
css: true
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ it("should able to import with different namedExports (async)", (done) => {
import("./style.module.css?named"),
]).then(([style1, style2, style3]) => {
expect(style1).toEqual(nsObj({ class: '-__style_module_css-class' }));
expect(style2).toEqual(nsObj({ default: nsObj({ class: '-__style_module_css_default-class' }) }));
expect(style2).toEqual(nsObj({
class: "-__style_module_css_default-class",
default: nsObj({ class: '-__style_module_css_default-class' })
}));
expect(style3).toEqual(nsObj({ class: '-__style_module_css_named-class' }));
done()
}, done)
Expand Down
13 changes: 12 additions & 1 deletion website/docs/en/config/experiments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,18 @@ module.exports = {
- **Type:** `boolean`
- **Default:** `true`

Once enabled, Rspack will enable native CSS support, Note that if you're using `style-loader` and `css-loader`, you should disable this option because `style-loader` and `css-loader` will conflict with native CSS.
Once enabled, Rspack will enable native CSS support, and CSS related parser and generator options.

- [`module.parser["css/auto"]`](/config/module.html#moduleparsercssauto)
- [`module.parser.css`](/config/module.html#moduleparsercss)
- [`module.parser["css/module"]`](/config/module.html#moduleparsercssmodule)
- [`module.generator["css/auto"]`](/config/module.html#modulegeneratorcssauto)
- [`module.generator.css`](/config/module.html#modulegeneratorcss)
- [`module.generator["css/module"]`](/config/module.html#modulegeneratorcssmodule)

:::warning
Note that if you're using `style-loader` and `css-loader`, you should disable this option because `style-loader` and `css-loader` will conflict with native CSS.
:::

## experiments.topLevelAwait

Expand Down
133 changes: 105 additions & 28 deletions website/docs/en/config/module.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ module.exports = {
};
```

### module.parser.asset.dataUrlCondition
### module.parser.asset

Parser options for `asset` modules.

#### module.parser.asset.dataUrlCondition

- **Type:** `{ maxSize: number }`
- **Default:** `{ maxSize: 8096 }`
Expand All @@ -105,14 +109,18 @@ module.exports = {
};
```

### module.parser.javascript.dynamicImportMode
### module.parser.javascript

Parser options for `javascript` modules.

#### module.parser.javascript.dynamicImportMode

- **Type:** `'lazy' | 'eager'`
- **Default:** `'lazy'`

Specifies global mode for dynamic import.

### module.parser.javascript.dynamicImportPrefetch
#### module.parser.javascript.dynamicImportPrefetch

<ApiMeta addedVersion="0.4.5" />

Expand All @@ -121,7 +129,7 @@ Specifies global mode for dynamic import.

Specifies global prefetch for dynamic import.

### module.parser.javascript.dynamicImportPreload
#### module.parser.javascript.dynamicImportPreload

<ApiMeta addedVersion="0.4.5" />

Expand Down Expand Up @@ -149,7 +157,15 @@ When use 'relative', rspack would generate relative URLs for `new URL()` syntax,
<img src="file:///path/to/project/dist/icon.svg" />
```

### module.parser["css/auto"].namedExports
### module.parser["css/auto"]

Parser options for `css/auto` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.parser["css/auto"].namedExports

<ApiMeta addedVersion="0.6.0" />

Expand All @@ -158,26 +174,51 @@ When use 'relative', rspack would generate relative URLs for `new URL()` syntax,

Use ES modules named export for css exports

When using `namedExports: true`, you can use namespace or named import:
When using `namedExports: true`, you can use namespace export or named export:

```js
// namespace export
import * as classes from './index.module.css';
import { class1 } from './index.module.css';
// named export
import { class1, class2 } from './index.module.css';
```

When using `namedExports: false`, you can use default import:
When using `namedExports: false`, in addition to namespace export and named export, default export can also be used:

```js
// namespace export
import * as classes from './index.module.css';
// named export
import { class1, class2 } from './index.module.css';
// default export
import classes from './index.module.css';
// default export and named export
import classes, { class1, class2 } from './index.module.css';
```

### module.parser.css.namedExports
### module.parser.css

Parser options for `css` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.parser.css.namedExports

<ApiMeta addedVersion="0.6.0" />

Same as [`module.parser["css/auto"].namedExports`](#moduleparsercssautonamedexports).

### module.parser["css/module"].namedExports
### module.parser["css/module"]

Parser options for `css/module` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.parser["css/module"].namedExports

<ApiMeta addedVersion="0.6.0" />

Expand Down Expand Up @@ -237,7 +278,11 @@ module.exports = {
};
```

### module.generator.asset.dataUrl
### module.generator.asset

Generator options for `asset` modules.

#### module.generator.asset.dataUrl

- **Type:** `Object | (options: { content: string, filename: string }) => string`
- **Default:** `{}`
Expand Down Expand Up @@ -277,21 +322,21 @@ module.exports = {
};
```

#### module.generator.asset.dataUrl.encoding
##### module.generator.asset.dataUrl.encoding

- **Type:** `false | 'base64'`
- **Default:** `'base64'`

When set to 'base64', module source will be encoded using Base64 algorithm. Setting encoding to false will disable encoding. Only for modules with module type `'asset'` or `'asset/inline'`.

#### module.generator.asset.dataUrl.mimetype
##### module.generator.asset.dataUrl.mimetype

- **Type:** `string`
- **Default:** `require('mime-types').lookup(ext)`

A mimetype for data URI. Resolves from module resource extension by default. Only for modules with module type `'asset'` or `'asset/inline'`.

### module.generator.asset.filename
#### module.generator.asset.filename

- **Type:** `string`
- **Default:** `undefined`
Expand All @@ -311,7 +356,7 @@ module.exports = {
};
```

### module.generator.asset.publicPath
#### module.generator.asset.publicPath

- **Type:** `string`
- **Default:** `undefined`
Expand All @@ -330,27 +375,43 @@ module.exports = {
};
```

### module.generator["asset/inline"].dataUrl
### module.generator["asset/inline"]

Generator options for `asset/inline` modules.

#### module.generator["asset/inline"].dataUrl

Same as [`module.generator["asset"].dataUrl`](#modulegeneratorassetdataurl).

#### module.generator["asset/inline"].dataUrl.encoding
##### module.generator["asset/inline"].dataUrl.encoding

Same as [`module.generator["asset"].dataUrl.encoding`](#modulegeneratorassetdataurlencoding).

#### module.generator["asset/inline"].dataUrl.mimetype
##### module.generator["asset/inline"].dataUrl.mimetype

Same as [`module.generator["asset"].dataUrl.mimetype`](#modulegeneratorassetdataurlmimetype).

### module.generator["asset/resource"].filename
### module.generator["asset/resource"]

Generator options for `asset/resource` modules.

#### module.generator["asset/resource"].filename

Same as [`module.generator["asset"].filename`](#modulegeneratorassetfilename).

### module.generator["asset/resource"].publicPath
#### module.generator["asset/resource"].publicPath

Same as [`module.generator["asset"].publicPath`](#modulegeneratorassetpublicpath).

### module.generator["css/auto"].exportsConvention
### module.generator["css/auto"]

Generator options for `css/auto` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.generator["css/auto"].exportsConvention

<ApiMeta addedVersion="0.6.0" />

Expand All @@ -359,7 +420,7 @@ Same as [`module.generator["asset"].publicPath`](#modulegeneratorassetpublicpath

Customize how css export names are exported to javascript modules, such as keeping them as is, transforming them to camel case, etc.

### module.generator["css/auto"].exportsOnly
#### module.generator["css/auto"].exportsOnly

<ApiMeta addedVersion="0.6.0" />

Expand All @@ -368,7 +429,7 @@ Customize how css export names are exported to javascript modules, such as keepi

Avoid generating and loading a stylesheet and only embed exports from css into output javascript files.

### module.generator["css/auto"].localIdentName
#### module.generator["css/auto"].localIdentName

<ApiMeta addedVersion="0.6.0" />

Expand All @@ -377,31 +438,47 @@ Avoid generating and loading a stylesheet and only embed exports from css into o

Customize the format of the local class names generated for css modules, besides the substitutions at [File-level](/config/output.html#file-context) and [Module-level](/config/output.html#module-context), also include `[uniqueName]` and `[local]`.

### module.generator.css.exportsConvention
### module.generator.css

Generator options for `css` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.generator.css.exportsConvention

<ApiMeta addedVersion="0.6.0" />

Same as [`module.generator["css/auto"].exportsConvention`](#modulegeneratorcssautoexportsconvention).

### module.generator.css.exportsOnly
#### module.generator.css.exportsOnly

<ApiMeta addedVersion="0.6.0" />

Same as [`module.generator["css/auto"].exportsOnly`](#modulegeneratorcssautoexportsonly).

### module.generator["css/module"].exportsConvention
### module.generator["css/module"]

Generator options for `css/module` modules.

:::warning
This configuration will only take effect when `experiments.css = true`.
:::

#### module.generator["css/module"].exportsConvention

<ApiMeta addedVersion="0.6.0" />

Same as [`module.generator["css/auto"].exportsConvention`](#modulegeneratorcssautoexportsconvention).

### module.generator["css/module"].exportsOnly
#### module.generator["css/module"].exportsOnly

<ApiMeta addedVersion="0.6.0" />

Same as [`module.generator["css/auto"].exportsOnly`](#modulegeneratorcssautoexportsonly).

### module.generator["css/module"].localIdentName
#### module.generator["css/module"].localIdentName

<ApiMeta addedVersion="0.6.0" />

Expand Down
Loading
Loading