docs:更新文档

This commit is contained in:
张益铭
2021-03-01 15:06:11 +08:00
parent 1542135ab0
commit 9064b372e8
5835 changed files with 904126 additions and 161722 deletions

View File

@@ -0,0 +1,3 @@
export function importModule(dirName, name) {
return import(`./module-dir-a/${name.substring(0, 2)}.js`);
}

View File

@@ -0,0 +1,3 @@
export function importModule(dirName, name) {
return import(`./${`module-dir-${dirName}`}` + '/' + name + '.js');
}

View File

@@ -0,0 +1,3 @@
export function importModule(name) {
return import(`./module-dir-a/${name}.js`);
}

View File

@@ -0,0 +1,3 @@
export function importModule(name) {
return import(`./module-dir-a/${name}`);
}

View File

@@ -0,0 +1,3 @@
export function importModule(dir, name) {
return import(`./${dir}/${name}.js`);
}

View File

@@ -0,0 +1,13 @@
export class Foo {
importModule(name) {
return import(`./module-dir-a/${name}.js`);
}
}
import(`./module-dir-a/${name}.js`).then((module) => {
console.log('imported', module);
});
export function importModuleFromDir(dir, name) {
return import(`./${dir}/${name}.js`);
}

View File

@@ -0,0 +1,3 @@
export function importModule(name) {
return import(`./root-module-${name}.js`);
}

View File

@@ -0,0 +1,3 @@
export function importModule(name) {
return import(`./module-dir-a/${name}.js`);
}

View File

@@ -0,0 +1,9 @@
import './module-dir-a/module-a-1.js';
export function importModuleA() {
return import(`./module-dir-a/module-a-2.js`);
}
export function importModuleB() {
return import('./' + 'module-dir-a' + '/' + 'module-a-2' + '.js');
}

View File

@@ -0,0 +1 @@
<!-- should not be resolved -->

View File

@@ -0,0 +1 @@
/* should not be resolved */

View File

@@ -0,0 +1 @@
console.log("a-1");

View File

@@ -0,0 +1 @@
console.log("a-2");

View File

@@ -0,0 +1 @@
console.log("a-2");

View File

@@ -0,0 +1 @@
console.log("a-2");

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1 @@
console.log("b-1");

View File

@@ -0,0 +1 @@
console.log("b-2");

View File

@@ -0,0 +1 @@
console.log("root-module-a.js");

View File

@@ -0,0 +1 @@
console.log("root-module-b.js");

View File

@@ -0,0 +1,3 @@
export function importModule(name) {
return import(`../module-dir-a/${name}.js`);
}

View File

@@ -0,0 +1,204 @@
import { join } from 'path';
import test from 'ava';
import { rollup } from 'rollup';
import dynamicImportVars from '..';
process.chdir(join(__dirname, 'fixtures'));
test('single dir', async (t) => {
const bundle = await rollup({
input: 'fixture-single-dir.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-single-dir.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('multiple dirs', async (t) => {
const bundle = await rollup({
input: 'fixture-multiple-dirs.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-multiple-dirs.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
require.resolve('./fixtures/module-dir-b/module-b-1.js'),
require.resolve('./fixtures/module-dir-b/module-b-2.js'),
require.resolve('./fixtures/sub-dir/fixture-upwards-path.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('upwards dir path', async (t) => {
const bundle = await rollup({
input: 'sub-dir/fixture-upwards-path',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/sub-dir/fixture-upwards-path.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('complex concatenation', async (t) => {
const bundle = await rollup({
input: 'fixture-complex-concat.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-complex-concat.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
require.resolve('./fixtures/module-dir-b/module-b-1.js'),
require.resolve('./fixtures/module-dir-b/module-b-2.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('CallExpression', async (t) => {
const bundle = await rollup({
input: 'fixture-call-expression.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-call-expression.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('own directory', async (t) => {
const bundle = await rollup({
input: 'fixture-own-dir.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-own-dir.js'),
require.resolve('./fixtures/root-module-a.js'),
require.resolve('./fixtures/root-module-b.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('multiple dynamic imports', async (t) => {
const bundle = await rollup({
input: 'fixture-multiple-imports.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-multiple-imports.js'),
require.resolve('./fixtures/module-dir-a/module-a-1.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
require.resolve('./fixtures/module-dir-b/module-b-1.js'),
require.resolve('./fixtures/module-dir-b/module-b-2.js'),
require.resolve('./fixtures/sub-dir/fixture-upwards-path.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test("doesn't change imports that should not be changed", async (t) => {
const bundle = await rollup({
input: 'fixture-unchanged.js',
plugins: [dynamicImportVars()],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [
require.resolve('./fixtures/fixture-unchanged.js'),
require.resolve('./fixtures/module-dir-a/module-a-2.js'),
];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('can exclude files', async (t) => {
const bundle = await rollup({
input: 'fixture-excluded.js',
plugins: [
dynamicImportVars({
exclude: ['fixture-excluded.js'],
}),
],
});
const { output } = await bundle.generate({ format: 'es' });
const expectedFiles = [require.resolve('./fixtures/fixture-excluded.js')];
t.deepEqual(
expectedFiles,
output.map((o) => o.facadeModuleId)
);
t.snapshot(output[0].code);
});
test('throws an error on failure', async (t) => {
let thrown;
try {
const bundle = await rollup({
input: 'fixture-extensionless.js',
plugins: [
dynamicImportVars({
exclude: ['fixture-excluded.js'],
}),
],
});
} catch (_) {
thrown = true;
}
t.is(thrown, true);
});

View File

@@ -0,0 +1,200 @@
# Snapshot report for `test/rollup-plugin-dynamic-import-variables.js`
The actual snapshot is saved in `rollup-plugin-dynamic-import-variables.js.snap`.
Generated by [AVA](https://ava.li).
## can exclude files
> Snapshot 1
`function importModule(name) {␊
return import(`./module-dir-a/${name}.js`);␊
}␊
export { importModule };␊
`
## complex concatenation
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
case './module-dir-b/module-b-1.js': return import('./module-b-1-72e7a68a.js');␊
case './module-dir-b/module-b-2.js': return import('./module-b-2-4b67cae0.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(dirName, name) {␊
return __variableDynamicImportRuntime0__(`./${`module-dir-${dirName}`}` + '/' + name + '.js');␊
}␊
export { importModule };␊
`
## doesn't change imports that should not be changed
> Snapshot 1
`console.log("a-1");␊
function importModuleA() {␊
return import('./module-a-2-173cc5f5.js');␊
}␊
function importModuleB() {␊
return import('./' + 'module-dir-a' + '/' + 'module-a-2' + '.js');␊
}␊
export { importModuleA, importModuleB };␊
`
## multiple dirs
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
case './module-dir-b/module-b-1.js': return import('./module-b-1-72e7a68a.js');␊
case './module-dir-b/module-b-2.js': return import('./module-b-2-4b67cae0.js');␊
case './sub-dir/fixture-upwards-path.js': return import('./fixture-upwards-path-89accf3a.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(dir, name) {␊
return __variableDynamicImportRuntime0__(`./${dir}/${name}.js`);␊
}␊
export { importModule };␊
`
## multiple dynamic imports
> Snapshot 1
`function __variableDynamicImportRuntime2__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
case './module-dir-b/module-b-1.js': return import('./module-b-1-72e7a68a.js');␊
case './module-dir-b/module-b-2.js': return import('./module-b-2-4b67cae0.js');␊
case './sub-dir/fixture-upwards-path.js': return import('./fixture-upwards-path-89accf3a.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function __variableDynamicImportRuntime1__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
class Foo {␊
importModule(name) {␊
return __variableDynamicImportRuntime0__(`./module-dir-a/${name}.js`);␊
}␊
}␊
__variableDynamicImportRuntime1__(`./module-dir-a/${name}.js`).then((module) => {␊
console.log('imported', module);␊
});␊
function importModuleFromDir(dir, name) {␊
return __variableDynamicImportRuntime2__(`./${dir}/${name}.js`);␊
}␊
export { Foo, importModuleFromDir };␊
`
## own directory
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './root-module-a.js': return import('./root-module-a-0cd41d7c.js');␊
case './root-module-b.js': return import('./root-module-b-decca893.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(name) {␊
return __variableDynamicImportRuntime0__(`./root-module-${name}.js`);␊
}␊
export { importModule };␊
`
## single dir
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(name) {␊
return __variableDynamicImportRuntime0__(`./module-dir-a/${name}.js`);␊
}␊
export { importModule };␊
`
## upwards dir path
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case '../module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case '../module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(name) {␊
return __variableDynamicImportRuntime0__(`../module-dir-a/${name}.js`);␊
}␊
export { importModule };␊
`
## CallExpression
> Snapshot 1
`function __variableDynamicImportRuntime0__(path) {␊
switch (path) {␊
case './module-dir-a/module-a-1.js': return import('./module-a-1-80325d58.js');␊
case './module-dir-a/module-a-2.js': return import('./module-a-2-173cc5f5.js');␊
default: return Promise.reject(new Error("Unknown variable dynamic import: " + path));␊
}␊
}␊
function importModule(dirName, name) {␊
return __variableDynamicImportRuntime0__(`./module-dir-a/${name.substring(0, 2)}.js`);␊
}␊
export { importModule };␊
`

View File

@@ -0,0 +1,237 @@
import { Parser } from 'acorn';
import dynamicImport from 'acorn-dynamic-import';
import test from 'ava';
import {
dynamicImportToGlob,
VariableDynamicImportError,
} from '../../src/dynamic-import-to-glob';
const CustomParser = Parser.extend(dynamicImport);
test('template literal with variable filename', (t) => {
const ast = CustomParser.parse('import(`./foo/${bar}.js`);', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*.js');
});
test('template literal with variable directory', (t) => {
const ast = CustomParser.parse('import(`./foo/${bar}/x.js`);', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*/x.js');
});
test('template literal with multiple variables', (t) => {
const ast = CustomParser.parse('import(`./${foo}/${bar}.js`);', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './*/*.js');
});
test('dynamic expression with variable filename', (t) => {
const ast = CustomParser.parse('import("./foo/".concat(bar,".js"));', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*.js');
});
test('dynamic expression with variable directory', (t) => {
const ast = CustomParser.parse('import("./foo/".concat(bar, "/x.js"));', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*/x.js');
});
test('dynamic expression with multiple variables', (t) => {
const ast = CustomParser.parse('import("./".concat(foo, "/").concat(bar,".js"));', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './*/*.js');
});
test('string concatenation', (t) => {
const ast = CustomParser.parse('import("./foo/" + bar + ".js");', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*.js');
});
test('string concatenation and template literals combined', (t) => {
const ast = CustomParser.parse('import("./" + `foo/${bar}` + ".js");', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*.js');
});
test('string literal in a template literal expression', (t) => {
const ast = CustomParser.parse('import(`${"./foo/"}${bar}.js`);', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*.js');
});
test('multiple variables are collapsed into a single *', (t) => {
const ast = CustomParser.parse('import(`./foo/${bar}${baz}/${x}${y}.js`);', {
sourceType: 'module',
});
const glob = dynamicImportToGlob(ast.body[0].expression.arguments[0]);
t.is(glob, './foo/*/*.js');
});
test('throws when dynamic import contains a *', (t) => {
const ast = CustomParser.parse('import(`./*${foo}.js`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0]);
} catch (e) {
error = e;
}
t.is(error.message, 'A dynamic import cannot contain * characters.');
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import contains a non + operator', (t) => {
const ast = CustomParser.parse('import("foo" - "bar.js");', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0]);
} catch (e) {
error = e;
}
t.is(error.message, '- operator is not supported.');
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import is a single variable', (t) => {
const ast = CustomParser.parse('import(foo);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". It cannot be statically analyzed. Variable dynamic imports must start with ./ and be limited to a specific directory. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import starts with a variable', (t) => {
const ast = CustomParser.parse('import(`${folder}/foo.js`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". It cannot be statically analyzed. Variable dynamic imports must start with ./ and be limited to a specific directory. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import starts with a /', (t) => {
const ast = CustomParser.parse('import(`/foo/${bar}.js`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". Variable absolute imports are not supported, imports must start with ./ in the static part of the import. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import does not start with ./', (t) => {
const ast = CustomParser.parse('import(`foo/${bar}.js`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". Variable bare imports are not supported, imports must start with ./ in the static part of the import. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});
test("throws when dynamic import imports it's own directory", (t) => {
const ast = CustomParser.parse('import(`./${foo}.js`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". Variable imports cannot import their own directory, place imports in a separate directory or make the import filename more specific. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});
test('throws when dynamic import imports does not contain a file extension', (t) => {
const ast = CustomParser.parse('import(`./foo/${bar}`);', {
sourceType: 'module',
});
let error;
try {
dynamicImportToGlob(ast.body[0].expression.arguments[0], '${sourceString}');
} catch (e) {
error = e;
}
t.is(
error.message,
'invalid import "${sourceString}". A file extension must be included in the static part of the import. For example: import(`./foo/${bar}.js`).'
);
t.true(error instanceof VariableDynamicImportError);
});