rollup-swc-preserve-directives
Advanced tools
Comparing version 0.4.0 to 0.5.0
Object.defineProperty(exports, '__esModule', { value: true }); | ||
var path = require('path'); | ||
var core = require('@swc/core'); | ||
var magicString = require('@napi-rs/magic-string'); | ||
const availableESExtensionsRegex = /\.(m|c)?(j|t)sx?$/; | ||
const tsExtensionsRegex = /\.(m|c)?tsx?$/; | ||
const directiveRegex = /^use (\w+)$/; | ||
const parseOptions = { | ||
ecmaVersion: 'latest', | ||
sourceType: 'module', | ||
// Use `allowHashBang: true` to prevent acorn from choking on shebangs | ||
allowHashBang: true, | ||
ranges: true, | ||
allowImportExportEverywhere: true, | ||
allowAwaitOutsideFunction: true | ||
}; | ||
function swcPreserveDirective() { | ||
@@ -24,86 +17,43 @@ const meta = { | ||
name: 'swc-render-directive', | ||
transform: { | ||
order: 'post', | ||
handler (code, id) { | ||
const ext = path.extname(id); | ||
if (!availableESExtensionsRegex.test(ext)) return null; | ||
let magicString$1 = null; | ||
/** | ||
* Here we are making 3 assumptions: | ||
* - shebang can only be at the first line of the file, otherwise it will not be recognized | ||
* - shebang can only contains one line | ||
* - shebang must starts with # and ! | ||
* | ||
* Those assumptions are also made by acorn, babel and swc: | ||
* | ||
* - acorn: https://github.com/acornjs/acorn/blob/8da1fdd1918c9a9a5748501017262ce18bb2f2cc/acorn/src/state.js#L78 | ||
* - babel: https://github.com/babel/babel/blob/86fee43f499c76388cab495c8dcc4e821174d4e0/packages/babel-parser/src/tokenizer/index.ts#L574 | ||
* - swc: https://github.com/swc-project/swc/blob/7bf4ab39b0e49759d9f5c8d7f989b3ed010d81a7/crates/swc_ecma_parser/src/lexer/mod.rs#L204 | ||
*/ if (code[0] === '#' && code[1] === '!') { | ||
let firstNewLineIndex = 0; | ||
for(let i = 2, len = code.length; i < len; i++){ | ||
const charCode = code.charCodeAt(i); | ||
if (charCode === 10 || charCode === 13 || charCode === 0x2028 || charCode === 0x2029) { | ||
firstNewLineIndex = i; | ||
break; | ||
} | ||
} | ||
if (firstNewLineIndex) { | ||
meta.shebang = code.slice(0, firstNewLineIndex); | ||
async transform (code, id) { | ||
const ext = path.extname(id); | ||
if (!availableESExtensionsRegex.test(ext)) return code; | ||
const isTypescript = tsExtensionsRegex.test(ext); | ||
const parseOptions = { | ||
syntax: isTypescript ? 'typescript' : 'ecmascript', | ||
[isTypescript ? 'tsx' : 'jsx']: true, | ||
privateMethod: true, | ||
classPrivateProperty: true, | ||
exportDefaultFrom: true, | ||
script: false, | ||
target: 'es2019' | ||
}; | ||
let magicString$1 = null; | ||
/** | ||
* @swc/core's node span doesn't start with 0 | ||
* https://github.com/swc-project/swc/issues/1366 | ||
*/ const { body, interpreter } = await core.parse(code, parseOptions); | ||
if (interpreter) { | ||
meta.shebang = `#!${interpreter}`; | ||
code = code.replace(new RegExp('^[\\s\\n]*' + meta.shebang.replace(/\//g, '\/') + '\\n*'), '') // Remove shebang from code | ||
; | ||
} | ||
for (const node of body){ | ||
if (node.type === 'ExpressionStatement') { | ||
if (node.expression.type === 'StringLiteral' && directiveRegex.test(node.expression.value)) { | ||
var _meta_directives, _id; | ||
(_meta_directives = meta.directives)[_id = id] || (_meta_directives[_id] = new Set()); | ||
meta.directives[id].add(node.expression.value); | ||
magicString$1 || (magicString$1 = new magicString.MagicString(code)); | ||
magicString$1.remove(0, firstNewLineIndex + 1); | ||
} | ||
} else { | ||
break; | ||
} | ||
/** | ||
* rollup's built-in parser returns an extended version of ESTree Node. | ||
*/ let ast = null; | ||
try { | ||
ast = this.parse(code, parseOptions); | ||
} catch (e) { | ||
console.log(e); | ||
this.warn({ | ||
code: 'PARSE_ERROR', | ||
message: `[rollup-swc-preserve-directives]: failed to parse "${id}" and extract the directives. make sure you have added "rollup-swc-preserve-directives" to the last of your plugins list, after swc/babel/esbuild/typescript or any other transform plugins.` | ||
}); | ||
return null; | ||
} | ||
if (ast.type === 'Program') { | ||
for (const node of ast.body){ | ||
if (node.type === 'ExpressionStatement') { | ||
let directive = null; | ||
/** | ||
* rollup and estree defines `directive` field on the `ExpressionStatement` node: | ||
* https://github.com/rollup/rollup/blob/fecf0cfe14a9d79bb0eff4ad475174ce72775ead/src/ast/nodes/ExpressionStatement.ts#L10 | ||
*/ if ('directive' in node) { | ||
directive = node.directive; | ||
} else if (node.expression.type === 'Literal' && typeof node.expression.value === 'string' && directiveRegex.test(node.expression.value)) { | ||
directive = node.expression.value; | ||
} | ||
if (directive) { | ||
var _meta_directives, _id; | ||
(_meta_directives = meta.directives)[_id = id] || (_meta_directives[_id] = new Set()); | ||
meta.directives[id].add(directive); | ||
magicString$1 || (magicString$1 = new magicString.MagicString(code)); | ||
/** | ||
* rollup has extended acorn node with the `start` and the `end` field | ||
* https://github.com/rollup/rollup/blob/fecf0cfe14a9d79bb0eff4ad475174ce72775ead/src/ast/nodes/shared/Node.ts#L33 | ||
* | ||
* However, typescript doesn't know that, so we add type guards for typescript | ||
* to infer. | ||
*/ if ('start' in node && typeof node.start === 'number' && 'end' in node && typeof node.end === 'number') { | ||
magicString$1.remove(node.start, node.end); | ||
} | ||
} | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
return { | ||
code: magicString$1 ? magicString$1.toString() : code, | ||
map: magicString$1 ? magicString$1.generateMap({ | ||
hires: true | ||
}).toMap() : null | ||
}; | ||
} | ||
return { | ||
code: magicString$1 ? magicString$1.toString() : code, | ||
map: magicString$1 ? magicString$1.generateMap({ | ||
hires: true | ||
}).toMap() : null | ||
}; | ||
}, | ||
@@ -141,2 +91,8 @@ renderChunk (code, chunk, { sourcemap }) { | ||
}; | ||
}, | ||
onLog (level, log) { | ||
if (log.code === 'MODULE_LEVEL_DIRECTIVE' && level === 'warn') { | ||
return false; | ||
} | ||
return this.warn(log); | ||
} | ||
@@ -143,0 +99,0 @@ }; |
{ | ||
"name": "rollup-swc-preserve-directives", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "Rollup plugin to preserve directives with SWC", | ||
@@ -33,2 +33,3 @@ "types": "./dist/index.d.ts", | ||
"peerDependencies": { | ||
"@swc/core": ">=1.3.79", | ||
"rollup": "^2.0.0 || ^3.0.0" | ||
@@ -40,3 +41,3 @@ }, | ||
"devDependencies": { | ||
"@swc/core": "^1.3.68", | ||
"@swc/core": "^1.3.82", | ||
"@swc/helpers": "^0.5.1", | ||
@@ -50,3 +51,3 @@ "@swc/jest": "^0.2.26", | ||
"jest": "^29.6.1", | ||
"rollup": "^3.26.2", | ||
"rollup": "^3.28.1", | ||
"rollup-plugin-swc3": "^0.9.0", | ||
@@ -53,0 +54,0 @@ "rollup2": "npm:rollup@^2.79.1", |
@@ -9,2 +9,5 @@ # rollup-swc-preserve-directives | ||
npm install rollup-swc-preserve-directives | ||
# You also need to install @swc/core as peer dependency | ||
npm install @swc/core | ||
``` | ||
@@ -11,0 +14,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
34
10503
3
200