mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-11-27 04:09:51 +08:00
feat: supports node native import (#5149)
This commit is contained in:
parent
a61b325650
commit
6483e1d1ea
10
package.json
10
package.json
@ -3,7 +3,7 @@
|
||||
"version": "2.36.0",
|
||||
"description": "A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"module": "es/index.mjs",
|
||||
"types": "es/index.d.ts",
|
||||
"unpkg": "dist/index.js",
|
||||
"jsdelivr": "dist/index.js",
|
||||
@ -46,6 +46,14 @@
|
||||
"web-types.json",
|
||||
"README.md"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./es/index.mjs",
|
||||
"require": "./lib/index.js",
|
||||
"types": "./es/index.d.ts"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"web-types": "./web-types.json",
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
|
180
scripts/post-build/complete-path.js
Normal file
180
scripts/post-build/complete-path.js
Normal file
@ -0,0 +1,180 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const glob = require('fast-glob')
|
||||
const babel = require('@babel/core')
|
||||
|
||||
/**
|
||||
* @param {('es' | 'lib')[]} formats
|
||||
*/
|
||||
module.exports.completePath = async (formats) => {
|
||||
await Promise.all(
|
||||
formats.map(async (format) => {
|
||||
const config = formatConfigs[format]
|
||||
const files = await glob('**/*.js', {
|
||||
cwd: config.root,
|
||||
absolute: true,
|
||||
onlyFiles: true
|
||||
})
|
||||
await Promise.all(
|
||||
files.map(async (filePath) => {
|
||||
const code = await fs.readFile(filePath, 'utf-8')
|
||||
await config.parse(code, filePath, path.dirname(filePath))
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const formatConfigs = {
|
||||
es: {
|
||||
root: path.join(__dirname, '../../es'),
|
||||
async parse (code, filePath, currentDir) {
|
||||
const suffix = '.mjs'
|
||||
const result = await babel.transformAsync(code, {
|
||||
root: this.root,
|
||||
babelrc: false,
|
||||
filename: filePath,
|
||||
sourceType: 'module',
|
||||
plugins: [
|
||||
{
|
||||
visitor: {
|
||||
ImportDeclaration: ({ node }) => {
|
||||
const source = node.source.value
|
||||
const parsedSource = parseSource(source, currentDir, suffix)
|
||||
if (parsedSource) {
|
||||
node.source.value = parsedSource
|
||||
}
|
||||
},
|
||||
ExportNamedDeclaration: ({ node }) => {
|
||||
if (node.source) {
|
||||
const source = node.source.value
|
||||
const parsedSource = parseSource(source, currentDir, suffix)
|
||||
if (parsedSource) {
|
||||
node.source.value = parsedSource
|
||||
}
|
||||
}
|
||||
},
|
||||
ExportAllDeclaration: ({ node }) => {
|
||||
const source = node.source.value
|
||||
const parsedSource = parseSource(source, currentDir, suffix)
|
||||
if (parsedSource) {
|
||||
node.source.value = parsedSource
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
const newFilePath = replaceExtname(filePath, suffix)
|
||||
await fs.writeFile(newFilePath, result.code || code)
|
||||
await fs.unlink(filePath)
|
||||
}
|
||||
},
|
||||
lib: {
|
||||
root: path.join(__dirname, '../../lib'),
|
||||
async parse (code, filePath, currentDir) {
|
||||
const suffix = '.js'
|
||||
const result = await babel.transformAsync(code, {
|
||||
root: this.root,
|
||||
babelrc: false,
|
||||
filename: filePath,
|
||||
plugins: [
|
||||
{
|
||||
visitor: {
|
||||
CallExpression: ({ node }) => {
|
||||
if (
|
||||
node.callee.type === 'Identifier' &&
|
||||
node.callee.name === 'require'
|
||||
) {
|
||||
const firstArg = node.arguments[0]
|
||||
if (firstArg.type === 'StringLiteral') {
|
||||
const source = firstArg.value
|
||||
const parsedSource = parseSource(source, currentDir, suffix)
|
||||
if (parsedSource) {
|
||||
firstArg.value = parsedSource
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
await fs.writeFile(filePath, result.code || code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {string} currentDir
|
||||
* @param {string} suffix
|
||||
* @returns {string | null}
|
||||
*/
|
||||
const parseSource = (source, currentDir, suffix) => {
|
||||
if (source.startsWith('.')) {
|
||||
const fullPath = joinPath(currentDir, source)
|
||||
return fs.existsSync(fullPath)
|
||||
? path.extname(fullPath)
|
||||
? source
|
||||
: joinPath(source, 'index' + suffix)
|
||||
: source + suffix
|
||||
} else {
|
||||
const [pkgName, subpath] = splitSource(source) || []
|
||||
return pkgName == null || subpath == null
|
||||
? null
|
||||
: guessFullPath(pkgName, subpath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} pkgName
|
||||
* @param {string} subpath
|
||||
* @return {string | null}
|
||||
*/
|
||||
const guessFullPath = (pkgName, subpath) => {
|
||||
const pkgPath = require.resolve(path.posix.join(pkgName, 'package.json'))
|
||||
const pkgRootPath = path.dirname(pkgPath)
|
||||
|
||||
let parsedSource = null
|
||||
const sourcePath = path.join(pkgRootPath, subpath)
|
||||
if (fs.existsSync(sourcePath + '.js')) {
|
||||
parsedSource = joinPath(pkgName, subpath + '.js')
|
||||
} else if (fs.existsSync(sourcePath + '.mjs')) {
|
||||
parsedSource = joinPath(pkgName, subpath + '.mjs')
|
||||
} else if (fs.existsSync(path.join(sourcePath, 'index.js'))) {
|
||||
parsedSource = joinPath(pkgName, subpath, 'index.js')
|
||||
} else if (fs.existsSync(path.join(sourcePath, 'index.mjs'))) {
|
||||
parsedSource = joinPath(pkgName, subpath, 'index.mjs')
|
||||
}
|
||||
return parsedSource
|
||||
}
|
||||
|
||||
const splitSource = (() => {
|
||||
const splitRegex = /^([\w-]+|@[\w-]+\/[\w-]+)(?:\/(.*))?$/
|
||||
/**
|
||||
* @param {string} source
|
||||
* @return {[string, string] | null}
|
||||
*/
|
||||
return (source) => {
|
||||
const matched = splitRegex.exec(source)
|
||||
if (!matched) return null
|
||||
return matched.slice(1)
|
||||
}
|
||||
})()
|
||||
|
||||
const replaceExtname = (filePath, ext) => {
|
||||
const oldExt = path.extname(filePath)
|
||||
if (!oldExt) return filePath + ext
|
||||
return joinPath(path.dirname(filePath), path.basename(filePath, oldExt) + ext)
|
||||
}
|
||||
|
||||
const joinPath = (firstPath, ...restPath) => {
|
||||
const joinedPath = normalizePath(path.join(firstPath, ...restPath))
|
||||
return firstPath.startsWith('./') ? './' + joinedPath : joinedPath
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
*/
|
||||
const normalizePath = (path) => path.replace(/\\/g, '/')
|
@ -5,6 +5,7 @@ const { terseCssr } = require('./terse-cssr')
|
||||
const { replaceDefine, outDirs, srcDir } = require('../utils')
|
||||
|
||||
const { genWebTypes } = require('./gen-web-types')
|
||||
const { completePath } = require('./complete-path')
|
||||
|
||||
;(async () => {
|
||||
await terseCssr()
|
||||
@ -18,6 +19,9 @@ const { genWebTypes } = require('./gen-web-types')
|
||||
"'date-fns'//": "'date-fns/esm'"
|
||||
})
|
||||
|
||||
// complete require and import source path
|
||||
await completePath(['es'])
|
||||
|
||||
// generate web-types.json for webstorm & vetur
|
||||
// web-types.json is only a very loose description for auto-complete
|
||||
// vscode is a much better choice
|
||||
|
Loading…
Reference in New Issue
Block a user