| | |
| | | |
| | | const source = ` |
| | | import { name } from 'mod\\u1011'; |
| | | import json from './json.json' assert { type: 'json' } |
| | | import json from './json.json' with { type: 'json' } |
| | | export var p = 5; |
| | | export function q () { |
| | | |
| | |
| | | export { x as 'external name' } from 'external'; |
| | | |
| | | // Comments provided to demonstrate edge cases |
| | | import /*comment!*/ ( 'asdf', { assert: { type: 'json' }}); |
| | | import /*comment!*/ ( 'asdf', { with: { type: 'json' }}); |
| | | import /*comment!*/.meta.asdf; |
| | | |
| | | // Source phase imports: |
| | |
| | | |
| | | // Returns "{ type: 'json' }" |
| | | source.slice(imports[1].a, imports[1].se); |
| | | // "a" = assert, -1 for no assertion |
| | | // "a" = attribute start, -1 for no import attributes |
| | | |
| | | // Parsed import attributes are available in `at` |
| | | // Returns [['type', 'json']] |
| | | imports[1].at; |
| | | // Returns 'json' |
| | | imports[1].at[0][1]; |
| | | |
| | | // Returns null (no attributes) |
| | | imports[0].at; |
| | | |
| | | // Returns "external" |
| | | source.slice(imports[2].s, imports[2].e); |
| | |
| | | |
| | | // Returns "asdf" (only for string literal dynamic imports) |
| | | imports[2].n |
| | | // Returns "import /*comment!*/ ( 'asdf', { assert: { type: 'json' } })" |
| | | // Returns "import /*comment!*/ ( 'asdf', { with: { type: 'json' } })" |
| | | source.slice(imports[3].ss, imports[3].se); |
| | | // Returns "'asdf'" |
| | | source.slice(imports[3].s, imports[3].e); |
| | | // Returns "( 'asdf', { assert: { type: 'json' } })" |
| | | // Returns "( 'asdf', { with: { type: 'json' } })" |
| | | source.slice(imports[3].d, imports[3].se); |
| | | // Returns "{ assert: { type: 'json' } }" |
| | | // Returns "{ with: { type: 'json' } }" |
| | | source.slice(imports[3].a, imports[3].se - 1); |
| | | |
| | | // For non-string dynamic import expressions: |
| | | // - n will be undefined |
| | | // - a is currently -1 even if there is an assertion |
| | | // - a is currently -1 even if there is an import attribute |
| | | // - e is currently the character before the closing ) |
| | | |
| | | // For nested dynamic imports, the se value of the outer import is -1 as end tracking does not |
| | |
| | | |
| | | Instead of Web Assembly, this uses an asm.js build which is almost as fast as the Wasm version ([see benchmarks below](#benchmarks)). |
| | | |
| | | ### Import Attributes |
| | | |
| | | The `a` field provides the index of the start of the `{` attributes bracket, or -1 for no attributes. |
| | | |
| | | The list of attribute key and value pairs are provided on the `at` field: |
| | | |
| | | ```js |
| | | const [imports] = parse(` |
| | | import json from './foo.json' with { type: 'json' }; |
| | | import './foo.css' with { type: 'css' }; |
| | | import pkg from 'pkg' with { type: 'json', integrity: 'sha384-...' }; |
| | | `); |
| | | |
| | | // Returns [['type', 'json']] |
| | | imports[0].at; |
| | | |
| | | // Returns [['type', 'css']] |
| | | imports[1].at; |
| | | |
| | | // Multiple attributes |
| | | // Returns [['type', 'json'], ['integrity', 'sha384-...']] |
| | | imports[2].at; |
| | | ``` |
| | | |
| | | The `at` field is an array of `[key, value]` tuples, or `null` if there are no attributes. |
| | | |
| | | Both keys and values support escape sequences: |
| | | |
| | | ```js |
| | | const [imports] = parse(` |
| | | import foo from './foo.js' with { "custom-key": "value" }; |
| | | import bar from './bar.js' with { "key\\nwith\\nnewlines": "value\\twith\\ttabs" }; |
| | | `); |
| | | |
| | | // Quoted keys are unquoted |
| | | // Returns [['custom-key', 'value']] |
| | | imports[0].at; |
| | | |
| | | // Escape sequences are processed |
| | | // Returns [['key\nwith\nnewlines', 'value\twith\ttabs']] |
| | | imports[1].at; |
| | | ``` |
| | | |
| | | ### Escape Sequences |
| | | |
| | | To handle escape sequences in specifier strings, the `.n` field of imported specifiers will be provided where possible. |