Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2fea0d7

Browse files
authored
Make initial ModuleInfo.meta mutable and maintain object identity (#4328)
1 parent a54b798 commit 2fea0d7

File tree

6 files changed

+95
-8
lines changed

6 files changed

+95
-8
lines changed

docs/05-plugin-development.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ Note the convention that custom options should be added using a property corresp
10551055
10561056
#### Custom module meta-data
10571057
1058-
Plugins can annotate modules with custom meta-data which can be accessed by themselves and other plugins via the [`resolveId`](guide/en/#resolveid), [`load`](guide/en/#load), and [`transform`](guide/en/#transform) hooks. This meta-data should always be JSON.stringifyable and will be persisted in the cache e.g. in watch mode.
1058+
Plugins can annotate modules with custom meta-data which can be set by themselves and other plugins via the [`resolveId`](guide/en/#resolveid), [`load`](guide/en/#load), and [`transform`](guide/en/#transform) hooks and accessed via [`this.getModuleInfo`](guide/en/#thisgetmoduleinfo), [`this.load`](guide/en/#thisload) and the [`moduleParsed`](guide/en/#moduleparsed) hook. This meta-data should always be JSON.stringifyable and will be persisted in the cache e.g. in watch mode.
10591059
10601060
```js
10611061
function annotatingPlugin() {
@@ -1087,6 +1087,26 @@ Note the convention that plugins that add or modify data should use a property c
10871087
10881088
If several plugins add meta-data or meta-data is added in different hooks, then these `meta` objects will be merged shallowly. That means if plugin `first` adds `{meta: {first: {resolved: "first"}}}` in the resolveId hook and `{meta: {first: {loaded: "first"}}}` in the load hook while plugin `second` adds `{meta: {second: {transformed: "second"}}}` in the `transform` hook, then the resulting `meta` object will be `{first: {loaded: "first"}, second: {transformed: "second"}}`. Here the result of the `resolveId` hook will be overwritten by the result of the `load` hook as the plugin was both storing them under its `first` top-level property. The `transform` data of the other plugin on the other hand will be placed next to it.
10891089
1090+
The `meta` object of a module is created as soon as Rollup starts loading a module and is updated for each lifecycle hook of the module. If you store a reference to this object, you can also update it manually. To access the meta object of a module that has not been loaded yet, you can trigger its creation and loading the module via [`this.load`](guide/en/#thisload):
1091+
1092+
```js
1093+
function plugin() {
1094+
return {
1095+
name: 'test',
1096+
buildStart() {
1097+
// trigger loading a module. We could also pass an initial "meta" object
1098+
// here, but it would be ignored if the module was already loaded via
1099+
// other means
1100+
this.load({ id: 'my-id' });
1101+
// the module info is now available, we do not need to await this.load
1102+
const meta = this.getModuleInfo('my-id').meta;
1103+
// we can also modify meta manually now
1104+
meta.test = { some: 'data' };
1105+
}
1106+
};
1107+
}
1108+
```
1109+
10901110
#### Direct plugin communication
10911111
10921112
For any other kind of inter-plugin communication, we recommend the pattern below. Note that `api` will never conflict with any upcoming plugin hooks.

src/Module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ export default class Module {
840840
this.info.syntheticNamedExports = syntheticNamedExports;
841841
}
842842
if (meta != null) {
843-
this.info.meta = { ...this.info.meta, ...meta };
843+
Object.assign(this.info.meta, meta);
844844
}
845845
}
846846

src/ModuleLoader.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export class ModuleLoader {
204204
return {
205205
external,
206206
id: resolvedId.id,
207-
meta: resolvedId.meta || EMPTY_OBJECT,
207+
meta: resolvedId.meta || {},
208208
moduleSideEffects:
209209
resolvedId.moduleSideEffects ?? this.hasModuleSideEffects(resolvedId.id, !!external),
210210
syntheticNamedExports: resolvedId.syntheticNamedExports ?? false
@@ -555,7 +555,7 @@ export class ModuleLoader {
555555
return {
556556
external: true,
557557
id: source,
558-
meta: EMPTY_OBJECT,
558+
meta: {},
559559
moduleSideEffects: this.hasModuleSideEffects(source, true),
560560
syntheticNamedExports: false
561561
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
const assert = require('assert');
2+
const path = require('path');
3+
const ID_MAIN = path.join(__dirname, 'main.js');
4+
5+
let initialMeta;
6+
7+
module.exports = {
8+
description: 'allows to freely modify moduleInfo.meta and maintain object identity',
9+
options: {
10+
plugins: [
11+
{
12+
name: 'first',
13+
buildStart() {
14+
this.load({ id: ID_MAIN });
15+
initialMeta = this.getModuleInfo(ID_MAIN).meta;
16+
initialMeta.buildStart = true;
17+
},
18+
load(id) {
19+
assert.strictEqual(id, ID_MAIN);
20+
const meta = this.getModuleInfo(ID_MAIN).meta;
21+
assert.deepStrictEqual(meta, { buildStart: true }, 'load');
22+
assert.strictEqual(meta, initialMeta);
23+
meta.load1a = true;
24+
return { code: `assert.ok(true);`, meta: { load1b: true } };
25+
},
26+
transform(code, id) {
27+
assert.strictEqual(id, ID_MAIN);
28+
const meta = this.getModuleInfo(ID_MAIN).meta;
29+
assert.deepStrictEqual(
30+
meta,
31+
{ buildStart: true, load1a: true, load1b: true },
32+
'transform'
33+
);
34+
assert.strictEqual(meta, initialMeta);
35+
meta.transform1a = true;
36+
return { code: `assert.ok(true);`, meta: { transform1b: true } };
37+
},
38+
buildEnd(error) {
39+
if (error) {
40+
throw error;
41+
}
42+
const meta = this.getModuleInfo(ID_MAIN).meta;
43+
assert.deepStrictEqual(
44+
meta,
45+
{
46+
buildStart: true,
47+
load1a: true,
48+
load1b: true,
49+
transform1a: true,
50+
transform1b: true,
51+
transform2: true
52+
},
53+
'buildEnd'
54+
);
55+
}
56+
},
57+
{
58+
name: 'second',
59+
transform(code, id) {
60+
assert.strictEqual(id, ID_MAIN);
61+
return { code: `assert.ok(true);`, meta: { transform2: true } };
62+
}
63+
}
64+
]
65+
}
66+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
assert.ok(true);

test/incremental/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,18 +293,17 @@ describe('incremental', () => {
293293
},
294294

295295
load(id) {
296-
assert.deepStrictEqual(this.getModuleInfo(id).meta, { test: { resolved: id } });
297296
return { code: modules[id], meta: { test: { loaded: id } } };
298297
},
299298

300299
transform(code, id) {
301300
transformCalls++;
302-
assert.deepStrictEqual(this.getModuleInfo(id).meta, { test: { loaded: id } });
301+
assert.deepStrictEqual(this.getModuleInfo(id).meta, { test: { loaded: id } }, 'transform');
303302
return { code, meta: { test: { transformed: id } } };
304303
},
305304

306305
moduleParsed({ id, meta }) {
307-
assert.deepStrictEqual(meta, { test: { transformed: id } });
306+
assert.deepStrictEqual(meta, { test: { transformed: id } }, 'moduleParsed');
308307
moduleParsedCalls++;
309308
},
310309

@@ -314,7 +313,8 @@ describe('incremental', () => {
314313
[
315314
{ id: 'entry', meta: { test: { transformed: 'entry' } } },
316315
{ id: 'foo', meta: { test: { transformed: 'foo' } } }
317-
]
316+
],
317+
'buildEnd'
318318
);
319319
}
320320
};

0 commit comments

Comments
 (0)