Skip to content

Commit

Permalink
Add option to configure import.meta.url resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Apr 1, 2019
1 parent 5665701 commit df9ae4e
Show file tree
Hide file tree
Showing 14 changed files with 94 additions and 15 deletions.
27 changes: 26 additions & 1 deletion docs/999-big-list-of-options.md
Expand Up @@ -614,14 +614,39 @@ Default: `true`
Whether to `Object.freeze()` namespace import objects (i.e. `import * as namespaceImportObject from...`) that are accessed dynamically.
#### output.importMetaUrl
Type: `((chunkId: string, moduleId: string) => string)`<br>
This allows the user to configure how Rollup handles `import.meta.url`. In ES modules, `import.meta.url` returns the URL of the current module, e.g. `http://server.net/bundle.js` for browsers or `file:///path/to/bundle.js` in Node.

By default for formats other than ES modules, Rollup replaces `import.meta.url` with code that attempts to match this behaviour by returning the dynamic URL of the current chunk. Note that all formats except CommonJS and UMD assume that they run in a browser environment where `URL` and `document` are available.

This behaviour can be customized by supplying a function, which will replace `import.meta.url` for all formats:

```javascript
// rollup.config.js
export default {
...,
output: {
...,

// this will use the original module id when resolving import.meta.url
importMetaUrl(chunkId, moduleId) {
return `"${moduleId}"`;
}
}
};

```
#### output.indent
Type: `boolean | string`<br>
CLI: `--indent`/`--no-indent`<br>
Default: `true`
The indent string to use, for formats that require code to be indented (`amd`, `iife`, `umd`, `system`). Can also be `false` (no indent), or `true` (the default – auto-indent)
```js
```javascript
// rollup.config.js
export default {
...,
Expand Down
4 changes: 3 additions & 1 deletion src/Chunk.ts
Expand Up @@ -800,7 +800,9 @@ export default class Chunk {
const module = this.orderedModules[i];
const code = this.renderedModuleSources[i];
for (const importMeta of module.importMetas) {
if (importMeta.renderFinalMechanism(code, this.id, options.format)) usesMechanism = true;
if (importMeta.renderFinalMechanism(code, this.id, options.format, options.importMetaUrl)) {
usesMechanism = true;
}
}
}
return usesMechanism;
Expand Down
25 changes: 14 additions & 11 deletions src/ast/nodes/MetaProperty.ts
Expand Up @@ -22,6 +22,7 @@ const importMetaUrlMechanisms: Record<string, (chunkId: string) => string> = {
`(require('u' + 'rl').URL)`
)} : ${getUrlFromDocument(chunkId)})`,
iife: chunkId => getUrlFromDocument(chunkId),
system: () => `module.meta.url`,
umd: chunkId =>
`(typeof document === 'undefined' ? ${getResolveUrl(
`'file:' + __filename`,
Expand Down Expand Up @@ -68,12 +69,15 @@ export default class MetaProperty extends NodeBase {
super.render(code, options);
}

renderFinalMechanism(code: MagicString, chunkId: string, format: string): boolean {
if (!this.rendered) return false;
renderFinalMechanism(
code: MagicString,
chunkId: string,
format: string,
renderImportMetaUrl: ((chunkId: string, moduleId: string) => string) | void
): boolean {
if (!this.included || !(this.parent instanceof MemberExpression)) return false;

if (this.parent instanceof MemberExpression === false) return false;

const parent = <MemberExpression>this.parent;
const parent = this.parent;

let importMetaProperty: string;
if (parent.property instanceof Identifier) importMetaProperty = parent.property.name;
Expand All @@ -89,12 +93,11 @@ export default class MetaProperty extends NodeBase {
return true;
}

if (format === 'system') {
code.overwrite(this.meta.start, this.meta.end, 'module');
} else if (importMetaProperty === 'url') {
const importMetaUrlMechanism = importMetaUrlMechanisms[format];
if (importMetaUrlMechanism)
code.overwrite(parent.start, parent.end, importMetaUrlMechanism(chunkId));
if (importMetaProperty === 'url') {
const getImportMetaUrl = renderImportMetaUrl || importMetaUrlMechanisms[format];
if (getImportMetaUrl) {
code.overwrite(parent.start, parent.end, getImportMetaUrl(chunkId, this.context.module.id));
}
return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/rollup/types.d.ts
Expand Up @@ -315,6 +315,7 @@ export interface OutputOptions {
format?: ModuleFormat;
freeze?: boolean;
globals?: GlobalsOption;
importMetaUrl?: (chunkId: string, moduleId: string) => string;
indent?: boolean;
interop?: boolean;
intro?: string | (() => string | Promise<string>);
Expand Down
1 change: 1 addition & 0 deletions src/utils/mergeOptions.ts
Expand Up @@ -248,6 +248,7 @@ function getOutputOptions(
format: format === 'esm' ? 'es' : format,
freeze: getOption('freeze', true),
globals: getOption('globals'),
importMetaUrl: getOption('importMetaUrl'),
indent: getOption('indent', true),
interop: getOption('interop', true),
intro: getOption('intro'),
Expand Down
13 changes: 13 additions & 0 deletions test/form/samples/configure-import-meta-url/_config.js
@@ -0,0 +1,13 @@
module.exports = {
description: 'allows to configure import.meta.url',
options: {
output: {
importMetaUrl(chunkId, moduleId) {
return `'${chunkId}/${moduleId
.split('/')
.slice(-2)
.join('/')}'`;
}
}
}
};
5 changes: 5 additions & 0 deletions test/form/samples/configure-import-meta-url/_expected/amd.js
@@ -0,0 +1,5 @@
define(['module'], function (module) { 'use strict';

console.log('amd.js/configure-import-meta-url/main.js');

});
3 changes: 3 additions & 0 deletions test/form/samples/configure-import-meta-url/_expected/cjs.js
@@ -0,0 +1,3 @@
'use strict';

console.log('cjs.js/configure-import-meta-url/main.js');
@@ -0,0 +1 @@
console.log('es.js/configure-import-meta-url/main.js');
6 changes: 6 additions & 0 deletions test/form/samples/configure-import-meta-url/_expected/iife.js
@@ -0,0 +1,6 @@
(function () {
'use strict';

console.log('iife.js/configure-import-meta-url/main.js');

}());
10 changes: 10 additions & 0 deletions test/form/samples/configure-import-meta-url/_expected/system.js
@@ -0,0 +1,10 @@
System.register([], function (exports, module) {
'use strict';
return {
execute: function () {

console.log('system.js/configure-import-meta-url/main.js');

}
};
});
8 changes: 8 additions & 0 deletions test/form/samples/configure-import-meta-url/_expected/umd.js
@@ -0,0 +1,8 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
}(function () { 'use strict';

console.log('umd.js/configure-import-meta-url/main.js');

}));
1 change: 1 addition & 0 deletions test/form/samples/configure-import-meta-url/main.js
@@ -0,0 +1 @@
console.log(import.meta.url);
4 changes: 2 additions & 2 deletions test/misc/optionList.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit df9ae4e

Please sign in to comment.