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

docs: addRuntimeModule and runtimeRequirementInTree #7938

Merged
merged 4 commits into from
Sep 24, 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
62 changes: 62 additions & 0 deletions website/docs/en/api/javascript-api/compilation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import CompilerType from '../../types/compiler.mdx';
import RspackErrorType from '../../types/rspack-error.mdx';
import CompilationDependenciesType from '../../types/compilation-dependencies.mdx';
import { Collapse, CollapsePanel } from '@components/Collapse';
import { ApiMeta } from '@components/ApiMeta';

<WebpackLicense from="https://webpack.js.org/api/compilation-object/" />

Expand Down Expand Up @@ -410,6 +411,67 @@ compiler.hooks.make.tap('MyPlugin', compilation => {
</CollapsePanel>
</Collapse>

### addRuntimeModule

<ApiMeta addedVersion="1.0.6" />

Add a custom runtime module to the compilation.

```ts
addRuntimeModule(
c: Chunk, // the runtime chunk which to add the runtime module
m: RuntimeModule, // the runtime module instance to add
): void;
```

The following code will add a runtime module which define `__webpack_require__.mock` to the `"main"` chunk:

```js title="rspack.config.js"
module.exports = {
entry: './index.js',
plugins: [
{
apply(compiler) {
const { RuntimeModule } = compiler.webpack;

class CustomRuntimeModule extends RuntimeModule {
constructor() {
super('custom');
}

generate(compilation) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering, is this compilation param a typo?

Webpack types do not have it:
https://github.com/webpack/webpack/blob/main/types.d.ts#L12839

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right. Pass the compilation as param of RuntimeModule.generate is not aligned with webpack. I will fix it in #8000

return `
__webpack_require__.mock = function() {
// ...
};
`;
}
}

compiler.hooks.thisCompilation.tap('CustomPlugin', compilation => {
compilation.hooks.runtimeRequirementInTree.tap(
'CustomPlugin',
(chunk, set) => {
if (chunk.name === 'main') {
compilation.addRuntimeModule(chunk, new CustomRuntimeModule());
}
},
);
});
},
},
],
};
```

When implementing a custom runtime module class, the following methods/properties can be overridden to control the behavior of the runtime module:

- Pass the `name` and `stage` parameters in the constructor to specify the module name and the insertion stage.
- Override the `generate()` method to control the generated code of the module.
- Override the `shouldIsolate()` method to control whether the module is wrapped in an IIFE.
- Override the `attach()` method to modify the behavior when the module is added.
- Modify its `fullHash` or `dependentHash` properties to control whether the module can be cached.

### rebuildModule

Triggers a re-build of the module.
Expand Down
137 changes: 120 additions & 17 deletions website/docs/en/api/plugin-api/compilation-hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CompilerType from '../../types/compiler.mdx';
import { Collapse, CollapsePanel } from '@components/Collapse';
import Columns from '@components/Columns';
import { NoSSR } from 'rspress/runtime';
import { ApiMeta } from '@components/ApiMeta';

# Compilation Hooks

Expand Down Expand Up @@ -268,12 +269,12 @@ direction LR
HookModuleRuntime --> HookAdditionalChunkRuntime(hooks.additionalChunkRuntimeRequirements)
HookAdditionalChunkRuntime --> HookChunkRuntime(hooks.runtimeRequirementInChunk)
HookChunkRuntime --> HookAdditionalTreeRuntime(<a href="#additionaltreeruntimerequirements">hooks.additionalTreeRuntimeRequirements</a>)
HookAdditionalTreeRuntime --> HookTreeRuntime(hooks.runtimeRequirementInTree)
HookAdditionalTreeRuntime --> HookTreeRuntime(<a href="#runtimerequirementintree">hooks.runtimeRequirementInTree</a>)
HookTreeRuntime --> HookAfterRuntimeRequirements(hooks.afterRuntimeRequirements)
HookTreeRuntime <--> HookRuntimeModule(<a href="#runtimemodule">hooks.runtimeModule</a>)

class HookBeforeRuntime,HookModuleRuntime,HookAdditionalChunkRuntime,HookChunkRuntime,HookTreeRuntime,HookAfterRuntimeRequirements, flow-hook-non-support
class HookAdditionalTreeRuntime,HookRuntimeModule flow-hook-partial-support
class HookBeforeRuntime,HookModuleRuntime,HookAdditionalChunkRuntime,HookChunkRuntime,HookAfterRuntimeRequirements, flow-hook-non-support
class HookAdditionalTreeRuntime,HookRuntimeModule,HookTreeRuntime flow-hook-partial-support
class ModuleCodeGeneration flow-process
end

Expand Down Expand Up @@ -554,29 +555,98 @@ Called after the tree optimization, at the beginning of the chunk modules optimi

## `additionalTreeRuntimeRequirements`

<Badge text="Read-only" type="info" />

Called after the tree runtime requirements collection.

- **Type:** `SyncHook<[Chunk, Set<RuntimeGlobals>]>`
- **Arguments:**
- `Chunk`: chunk instance
- `Set<RuntimeGlobals>`: runtime requirements

<Collapse>
<CollapsePanel
className="collapse-code-panel"
header="RuntimeGlobals.ts"
key="RuntimeGlobals"
>
```ts enum RuntimeGlobals {}
```
</CollapsePanel>
</Collapse>
Additional builtin runtime modules can be added here by modifying the runtime requirements set.

## `runtimeModule`
```js title="rspack.config.js"
module.exports = {
entry: './index.js',
plugins: [
{
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
compiler.hooks.thisCompilation.tap('CustomPlugin', compilation => {
compilation.hooks.additionalTreeRuntimeRequirements.tap(
'CustomPlugin',
(_, set) => {
// add a runtime module which define `__webpack_require__.h`
set.add(RuntimeGlobals.getFullHash);
},
);
});
},
},
],
};
```

<Badge text="Read-only" type="info" />
```js title="index.js"
// will print hash of this compilation
console.log(__webpack_require__.h);
```

## `runtimeRequirementInTree`

<ApiMeta addedVersion="1.0.6" />

Called during adding runtime modules to the compilation.

- **Type:** `SyncBailHook<[Chunk, Set<RuntimeGlobals>]>`
- **Arguments:**
- `Chunk`: chunk instance
- `Set<RuntimeGlobals>`: runtime requirements

Additional builtin runtime modules can be added here by modifying the runtime requirements set or calling [`compilation.addRuntimeModule`](/api/javascript-api/compilation#addruntimemodule) to add custom runtime modules.

```js title="rspack.config.js"
module.exports = {
entry: './index.js',
plugins: [
{
apply(compiler) {
const { RuntimeGlobals, RuntimeModule } = compiler.webpack;
class CustomRuntimeModule extends RuntimeModule {
constructor() {
super('custom');
}

generate(compilation) {
return `
__webpack_require__.mock = function(file) {
return ${RuntimeGlobals.publicPath} + "/subpath/" + file;
};
`;
}
}

compiler.hooks.thisCompilation.tap('CustomPlugin', compilation => {
compilation.hooks.runtimeRequirementInTree.tap(
'CustomPlugin',
(chunk, set) => {
// add a runtime module to access public path
set.add(RuntimeGlobals.publicPath);
compilation.addRuntimeModule(chunk, new CustomRuntimeModule());
},
);
});
},
},
],
};
```

```js title="index.js"
// will print "/subpath/index.js"
console.log(__webpack_require__.mock('index.js'));
```

## `runtimeModule`

Called after a runtime module is added into the compilation.

Expand All @@ -585,6 +655,39 @@ Called after a runtime module is added into the compilation.
- `RuntimeModule`: runtime module instance
- `Chunk`: chunk instance

Generated code of this runtime module can be modified through its `source` property.

```js title="rspack.config.js"
module.exports = {
plugins: [
{
apply(compiler) {
const { RuntimeGlobals } = compiler.webpack;
compiler.hooks.compilation.tap('CustomPlugin', compilation => {
compilation.hooks.runtimeModule.tap(
'CustomPlugin',
(module, chunk) => {
if (module.name === 'public_path' && chunk.name === 'main') {
const originSource = module.source.source.toString('utf-8');
module.source.source = Buffer.from(
`${RuntimeGlobals.publicPath} = "/override/public/path";\n`,
'utf-8',
);
}
},
);
});
},
},
],
};
```

```js title="index.js"
// will print "/override/public/path"
console.log(__webpack_require__.p);
```

<Collapse>
<CollapsePanel
className="collapse-code-panel"
Expand Down
62 changes: 62 additions & 0 deletions website/docs/zh/api/javascript-api/compilation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import CompilerType from '../../types/compiler.mdx';
import RspackErrorType from '../../types/rspack-error.mdx';
import CompilationDependenciesType from '../../types/compilation-dependencies.mdx';
import { Collapse, CollapsePanel } from '@components/Collapse';
import { ApiMeta } from '@components/ApiMeta';

<WebpackLicense from="https://webpack.docschina.org/api/compilation-object/" />

Expand Down Expand Up @@ -410,6 +411,67 @@ compiler.hooks.make.tap('MyPlugin', compilation => {
</CollapsePanel>
</Collapse>

### addRuntimeModule

<ApiMeta addedVersion="1.0.6" />

添加一个自定义的运行时模块。

```ts
addRuntimeModule(
c: Chunk, // 运行时模块所在的 Chunk
m: RuntimeModule, // 运行时模块的实例
): void;
```

以下代码添加一个运行时模块,该模块定义 `__webpack_require__.mock`,并添加到 `"main"` Chunk 中:

```js title="rspack.config.js"
module.exports = {
entry: './index.js',
plugins: [
{
apply(compiler) {
const { RuntimeModule } = compiler.webpack;

class CustomRuntimeModule extends RuntimeModule {
constructor() {
super('custom', RuntimeModule.STAGE_NORMAL);
}

generate(compilation) {
return `
__webpack_require__.mock = function() {
// ...
};
`;
}
}

compiler.hooks.thisCompilation.tap('CustomPlugin', compilation => {
compilation.hooks.runtimeRequirementInTree.tap(
'CustomPlugin',
(chunk, set) => {
if (chunk.name === 'main') {
compilation.addRuntimeModule(chunk, new CustomRuntimeModule());
}
},
);
});
},
},
],
};
```

实现自定义的运行时模块 Class 时,可覆盖如下方法/属性来控制其行为:

- 在构造器中传入 `name` 和 `stage` 参数来指定模块名称和插入的阶段
- 覆盖 `generate()` 方法以控制模块生成的代码
- 覆盖 `shouldIsolate()` 方法以控制模块是否包裹在 IIFE 当中
- 覆盖 `attach()` 方法以修改在模块被添加时的行为
- 修改其 `fullHash` 或 `dependentHash` 属性以控制模块是否可被缓存

### rebuildModule

重新构建指定模块。
Expand Down
Loading
Loading