Skip to content

Commit

Permalink
Refine transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jan 23, 2020
1 parent f9fe2bc commit 16e4cff
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 154 deletions.
38 changes: 17 additions & 21 deletions src/utils/PluginCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,25 @@ export function createPluginCache(cache: SerializablePluginCache): PluginCache {
};
}

export function getTrackedPluginCache(pluginCache: PluginCache) {
const trackedCache = {
cache: {
has(id: string) {
trackedCache.used = true;
return pluginCache.has(id);
},
get(id: string) {
trackedCache.used = true;
return pluginCache.get(id);
},
set(id: string, value: any) {
trackedCache.used = true;
return pluginCache.set(id, value);
},
delete(id: string) {
trackedCache.used = true;
return pluginCache.delete(id);
}
export function getTrackedPluginCache(pluginCache: PluginCache, onUse: () => void): PluginCache {
return {
has(id: string) {
onUse();
return pluginCache.has(id);
},
get(id: string) {
onUse();
return pluginCache.get(id);
},
used: false
set(id: string, value: any) {
onUse();
return pluginCache.set(id, value);
},
delete(id: string) {
onUse();
return pluginCache.delete(id);
}
};
return trackedCache;
}

export const NO_CACHE: PluginCache = {
Expand Down
47 changes: 15 additions & 32 deletions src/utils/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
DecodedSourceMapOrMissing,
EmittedFile,
Plugin,
PluginCache,
PluginContext,
RollupError,
RollupWarning,
Expand Down Expand Up @@ -33,9 +32,9 @@ export default function transform(
const transformDependencies: string[] = [];
const emittedFiles: EmittedFile[] = [];
let customTransformCache = false;
const useCustomTransformCache = () => (customTransformCache = true);
let moduleSideEffects: boolean | null = null;
let syntheticNamedExports: boolean | null = null;
let trackedPluginCache: { cache: PluginCache; used: boolean };
let curPlugin: Plugin;
const curSource: string = source.code;

Expand All @@ -45,17 +44,6 @@ export default function transform(
result: TransformResult,
plugin: Plugin
) {
// TODO Lukas this could also be run once at the end?
if (!customTransformCache) {
if (trackedPluginCache.used) {
// track which plugins use the custom this.cache to opt-out of transform caching
customTransformCache = true;
} else {
// files emitted by a transform hook need to be emitted again if the hook is skipped
if (emittedFiles.length) module.transformFiles = emittedFiles;
}
}

if (typeof result === 'string') {
result = {
ast: undefined,
Expand All @@ -76,7 +64,8 @@ export default function transform(
return code;
}

// strict null check allows 'null' maps to not be pushed to the chain, while 'undefined' gets the missing map warning
// strict null check allows 'null' maps to not be pushed to the chain,
// while 'undefined' gets the missing map warning
if (result.map !== null) {
const map = decodedSourcemap(result.map);
sourcemapChain.push(map || { missing: true, plugin: plugin.name });
Expand All @@ -87,20 +76,18 @@ export default function transform(
return result.code;
}

let setAssetSourceErr: any;

return graph.pluginDriver
.hookReduceArg0<any, string>(
'transform',
[curSource, id],
transformReducer,
(pluginContext, plugin) => {
curPlugin = plugin;
if (curPlugin.cacheKey) customTransformCache = true;
else trackedPluginCache = getTrackedPluginCache(pluginContext.cache);
return {
...pluginContext,
cache: trackedPluginCache ? trackedPluginCache.cache : pluginContext.cache,
cache: customTransformCache
? pluginContext.cache
: getTrackedPluginCache(pluginContext.cache, useCustomTransformCache),
warn(warning: RollupWarning | string, pos?: number | { column: number; line: number }) {
if (typeof warning === 'string') warning = { message: warning } as RollupWarning;
if (pos) augmentCodeLocation(warning, pos, curSource, id);
Expand Down Expand Up @@ -133,18 +120,11 @@ export default function transform(
transformDependencies.push(id);
pluginContext.addWatchFile(id);
},
setAssetSource(assetReferenceId, source) {
pluginContext.setAssetSource(assetReferenceId, source);
if (!customTransformCache && !setAssetSourceErr) {
try {
return this.error({
code: 'INVALID_SETASSETSOURCE',
message: `setAssetSource cannot be called in transform for caching reasons. Use emitFile with a source, or call setAssetSource in another hook.`
});
} catch (err) {
setAssetSourceErr = err;
}
}
setAssetSource() {
return this.error({
code: 'INVALID_SETASSETSOURCE',
message: `setAssetSource cannot be called in transform for caching reasons. Use emitFile with a source, or call setAssetSource in another hook.`
});
},
getCombinedSourcemap() {
const combinedMap = collapseSourcemap(
Expand Down Expand Up @@ -173,7 +153,10 @@ export default function transform(
)
.catch(err => throwPluginError(err, curPlugin.name, { hook: 'transform', id }))
.then(code => {
if (!customTransformCache && setAssetSourceErr) throw setAssetSourceErr;
if (!customTransformCache) {
// files emitted by a transform hook need to be emitted again if the hook is skipped
if (emittedFiles.length) module.transformFiles = emittedFiles;
}

return {
ast: ast!,
Expand Down
14 changes: 13 additions & 1 deletion test/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,12 @@ describe('hooks', () => {
this.cache.set('asdf', 'asdf');
return `alert('hello world')`;
}
},
{
name: 'y',
transform(code) {
return code + `;alert('world')`;
}
}
]
})
Expand All @@ -804,6 +810,12 @@ describe('hooks', () => {
assert.ok(!this.cache.has('asdf'));
return `alert('hello')`;
}
},
{
name: 'y',
transform(code) {
return code + `;alert('world')`;
}
}
]
})
Expand All @@ -814,7 +826,7 @@ describe('hooks', () => {
})
)
.then(({ output }) => {
assert.strictEqual(output[0].code.trim(), `alert('hello');`);
assert.strictEqual(output[0].code.trim(), `alert('hello');alert('world');`);
}));

it('supports renderStart hook', () => {
Expand Down
119 changes: 19 additions & 100 deletions test/watch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ describe('rollup.watch', () => {

it('respects changed watched modules that are already part of the graph in the transform hook', () => {
return sander
.copydir('test/watch/samples/watch-files')
.copydir('test/watch/samples/dependencies')
.to('test/_tmp/input')
.then(() => {
watcher = rollup.watch({
Expand All @@ -1098,12 +1098,15 @@ describe('rollup.watch', () => {
format: 'cjs'
},
plugins: {
transform() {
this.addWatchFile('test/_tmp/input/main.js');
return `export default "${sander
.readFileSync('test/_tmp/input/main.js')
.toString()
.trim()}"`;
transform(code, id) {
if (id.endsWith('dep1.js')) {
this.addWatchFile(path.resolve('test/_tmp/input/dep2.js'));
const text = sander
.readFileSync('test/_tmp/input/dep2.js')
.toString()
.trim();
return `export default ${JSON.stringify(text)}`;
}
}
}
});
Expand All @@ -1114,15 +1117,21 @@ describe('rollup.watch', () => {
'BUNDLE_END',
'END',
() => {
assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;');
sander.writeFileSync('test/_tmp/input/main.js', 'next');
assert.strictEqual(
run('../_tmp/output/bundle.js'),
`dep1: "export default 'dep2';", dep2: "dep2"`
);
sander.writeFileSync('test/_tmp/input/dep2.js', 'export default "next";');
},
'START',
'BUNDLE_START',
'BUNDLE_END',
'END',
() => {
assert.strictEqual(run('../_tmp/output/bundle.js'), 'next');
assert.strictEqual(
run('../_tmp/output/bundle.js'),
`dep1: "export default "next";", dep2: "next"`
);
}
]);
});
Expand Down Expand Up @@ -1217,94 +1226,4 @@ describe('rollup.watch', () => {
});
});
});

describe('deprecated features', () => {
// TODO Lukas why is this green?
it('watches and rebuilds transform dependencies that are modules', () => {
return sander
.copydir('test/watch/samples/watch-files')
.to('test/_tmp/input')
.then(() => {
watcher = rollup.watch({
input: 'test/_tmp/input/main.js',
output: {
file: 'test/_tmp/output/bundle.js',
format: 'cjs'
},
plugins: {
transform() {
const dependencies = ['./main.js'];
const text = sander
.readFileSync('test/_tmp/input/main.js')
.toString()
.trim();
return { code: `export default "${text}"`, dependencies };
}
}
});

return sequence(watcher, [
'START',
'BUNDLE_START',
'BUNDLE_END',
'END',
() => {
assert.strictEqual(run('../_tmp/output/bundle.js'), 'export default 42;');
sander.writeFileSync('test/_tmp/input/main.js', 'next');
},
'START',
'BUNDLE_START',
'BUNDLE_END',
'END',
() => {
assert.strictEqual(run('../_tmp/output/bundle.js'), 'next');
}
]);
});
});

// TODO Lukas why is this green?
it('watches transform dependencies when there are multiple modules', () => {
let v = 1;
return sander
.copydir('test/watch/samples/watch-files-multiple')
.to('test/_tmp/input')
.then(() => {
watcher = rollup.watch({
input: 'test/_tmp/input/index.js',
output: {
file: 'test/_tmp/output/bundle.js',
format: 'cjs'
},
plugins: {
transform(code, id) {
if (!id.includes('dep.txt')) {
return;
}
this.addWatchFile('test/_tmp/input/depdep.txt');
return `export default ${v++};`;
}
}
});

return sequence(watcher, [
'START',
'BUNDLE_START',
'BUNDLE_END',
'END',
() => {
assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 1, first: 'b' });
sander.writeFileSync('test/_tmp/input/depdep.txt', 'changed');
},
'START',
'BUNDLE_START',
'BUNDLE_END',
'END',
() => {
assert.deepStrictEqual(run('../_tmp/output/bundle.js'), { dep: 2, first: 'b' });
}
]);
});
});
});
});
1 change: 1 addition & 0 deletions test/watch/samples/dependencies/dep1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'dep1';
1 change: 1 addition & 0 deletions test/watch/samples/dependencies/dep2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'dep2';
3 changes: 3 additions & 0 deletions test/watch/samples/dependencies/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import dep1 from './dep1.js';
import dep2 from './dep2.js';
export default `dep1: "${dep1}", dep2: "${dep2}"`;

0 comments on commit 16e4cff

Please sign in to comment.