packages/layers/geojson/scripts/fixTscExtension.mjs (116 lines of code) (raw):

/** * DO NOT EDIT * AUTO COPIED FROM ROOT/shared */ /** * fix es module file extensions * * es module requires file extension in `import`, but tsc ignored it. * * `import` without extension still work with webpack in curtain circumstances. * @link /docs/index.md * should not depend on it. */ /** * @NOTE 这种方案会破坏掉 sourcemap ,但是考虑到 sourcemap 的原理,如果修改的内容都在行尾,应该没有问题 * @BTW 生成的js完全是可读的,sourcemap完全可以去掉来节约编译时间 */ /** * String.prototype.replaceAll() polyfill * https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/ * @author Chris Ferdinandi * @license MIT */ if (!String.prototype.replaceAll) { String.prototype.replaceAll = function (str, newStr) { // If a regex pattern if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') { return this.replace(str, newStr) } // If a string return this.replace(new RegExp(str, 'g'), newStr) } } import { dirname } from 'path' import { fileURLToPath } from 'url' const __dirname = dirname(fileURLToPath(import.meta.url)) import { accessSync, constants } from 'fs' import { readFile, writeFile } from 'fs/promises' import path from 'path' // https://regex101.com/r/UK27wD/1 const reImport = /(import(?:["'\s\w*{}/\n\r\t, ]+from\s*)?\s*["']\s*)([./@\w_-]+)(["'\s].*)$/gm // https://regex101.com/r/5iG1QQ/1 const reExport = /(export(?:["'\s\w*{}/\n\r\t, ]+from\s*)?["']\s*)([./@\w_-]+)(["'\s].*)$/gm async function editFile(file) { const text = (await readFile(file)).toString() // 需要 file 在闭包里 function replacement(match, before, moduleName, after) { if ( isFile(moduleName) && !( moduleName.endsWith('.js') || moduleName.endsWith('.mjs') || moduleName.endsWith('.node') || moduleName.endsWith('.wasm') || moduleName.endsWith('.bin') ) ) { // console.log('find:', match) // 本地引用需要添加后缀名 // 检查被引用的模块是否存在 const jsTarget = path.resolve(path.dirname(file), moduleName + '.js') const mjsTarget = path.resolve(path.dirname(file), moduleName + '.mjs') let extension try { accessSync(jsTarget, constants.R_OK) extension = '.js' } catch (error) { // js target 不存在 // 尝试 mjs try { accessSync(mjsTarget, constants.R_OK) extension = '.mjs' } catch (error) { console.warn( '\x1b[33m%s\x1b[0m', `找不到被引用的模块,将使用 .js 作为后缀:${moduleName} in ${path.relative( path.resolve(__dirname, '../'), file )}` ) extension = '.js' } } const newModuleName = moduleName + extension const replacement = before + newModuleName + after // console.log('---->', replacement) return replacement } else { return match } } const newText = text.replace(reImport, replacement) const newText2 = newText.replace(reExport, replacement) await writeFile(file, newText2) } import glob from 'glob' glob(path.resolve(__dirname, '../dist') + '/**/*.js', {}, (err, files) => { // console.log(files) files.forEach(async (file) => { await editFile(path.resolve(__dirname, '../', file)) }) }) function isFile(moduleName) { if (moduleName.startsWith('.') || moduleName.startsWith('/')) { return true } const slashes = moduleName.split('/').length - 1 const hasAt = moduleName.startsWith('@') if (hasAt && slashes > 1) { return true } if (!hasAt && slashes > 0) { return true } return false }