mirror of
				https://gitee.com/vant-contrib/vant.git
				synced 2025-10-27 01:32:10 +08:00 
			
		
		
		
	feat(@vant/cli): using esbuild to transform script (#10143)
* feat(@vant/cli): using esbuild to transform script * chore: update babel doc * chore: update lock * chore: update * fix: format
This commit is contained in:
		
							parent
							
								
									7b214cb87c
								
							
						
					
					
						commit
						1890cf6607
					
				| @ -1,30 +0,0 @@ | ||||
| module.exports = function (api, options) { | ||||
|   if (api) { | ||||
|     api.cache.never(); | ||||
|   } | ||||
| 
 | ||||
|   const { BABEL_MODULE, NODE_ENV } = process.env; | ||||
|   const isTest = NODE_ENV === 'test'; | ||||
|   const useESModules = BABEL_MODULE !== 'commonjs' && !isTest; | ||||
| 
 | ||||
|   return { | ||||
|     presets: [ | ||||
|       [ | ||||
|         require.resolve('@babel/preset-env'), | ||||
|         { | ||||
|           modules: useESModules ? false : 'commonjs', | ||||
|           loose: options.loose, | ||||
|         }, | ||||
|       ], | ||||
|       require.resolve('@babel/preset-typescript'), | ||||
|     ], | ||||
|     plugins: [ | ||||
|       [ | ||||
|         require.resolve('@vue/babel-plugin-jsx'), | ||||
|         { | ||||
|           enableObjectSlots: options.enableObjectSlots, | ||||
|         }, | ||||
|       ], | ||||
|     ], | ||||
|   }; | ||||
| }; | ||||
| @ -21,8 +21,6 @@ | ||||
|     - [site.simulator.url](#sitesimulatorurl) | ||||
|     - [site.htmlMeta](#sitehtmlmeta) | ||||
|     - [site.enableVConsole](#siteenablevconsole) | ||||
|   - [Babel](#babel) | ||||
|     - [默认配置](#----) | ||||
|   - [Postcss](#postcss) | ||||
|     - [默认配置](#-----1) | ||||
|   - [browserslist](#browserslist) | ||||
| @ -337,29 +335,6 @@ module.exports = { | ||||
| 
 | ||||
| 是否在 dev 时开启 [vConsole](https://github.com/Tencent/vConsole) 调试,用于移动端 debug。 | ||||
| 
 | ||||
| ## Babel | ||||
| 
 | ||||
| 通过根目录下的`babel.config.js`文件可以对 Babel 进行配置。 | ||||
| 
 | ||||
| ### 默认配置 | ||||
| 
 | ||||
| 推荐使用`vant-cli`内置的 preset,配置如下: | ||||
| 
 | ||||
| ```js | ||||
| module.exports = { | ||||
|   presets: ['@vant/cli/preset'], | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| `@vant/cli/preset`中默认包含了以下插件: | ||||
| 
 | ||||
| - @babel/preset-env(不含 core-js) | ||||
| - @babel/preset-typescript | ||||
| - @babel/plugin-transform-object-assign | ||||
| - @babel/plugin-proposal-optional-chaining | ||||
| - @babel/plugin-proposal-nullish-coalescing-operator | ||||
| - @vue/babel-preset-jsx | ||||
| 
 | ||||
| ## Postcss | ||||
| 
 | ||||
| 通过根目录下的`postcss.config.js`文件可以对 Postcss 进行配置。 | ||||
| @ -378,7 +353,7 @@ module.exports = { | ||||
| 
 | ||||
| ## browserslist | ||||
| 
 | ||||
| 推荐在`package.json`文件里添加 browserslist 字段,这个值会被`@babel/preset-env`和`autoprefixer`用来确定目标浏览器的版本,保证编译后代码的兼容性。 | ||||
| 推荐在 `package.json` 文件里添加 browserslist 字段,这个值会被 `autoprefixer` 用来确定目标浏览器的版本,保证编译后代码的兼容性。 | ||||
| 
 | ||||
| 在移动端浏览器中使用,可以添加如下配置: | ||||
| 
 | ||||
|  | ||||
| @ -14,7 +14,6 @@ project | ||||
| │   ├─ home.md       # 文档首页 | ||||
| │   └─ changelog.md  # 更新日志 | ||||
| │ | ||||
| ├─ babel.config.js    # Babel 配置文件 | ||||
| ├─ vant.config.mjs    # Vant Cli 配置文件 | ||||
| ├─ package.json | ||||
| └─ README.md | ||||
|  | ||||
| @ -21,8 +21,7 @@ | ||||
|     "cjs", | ||||
|     "site", | ||||
|     "template", | ||||
|     "bin.js", | ||||
|     "preset.cjs" | ||||
|     "bin.js" | ||||
|   ], | ||||
|   "keywords": [ | ||||
|     "vant" | ||||
| @ -49,7 +48,6 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@babel/core": "^7.16.0", | ||||
|     "@babel/preset-env": "^7.16.0", | ||||
|     "@babel/preset-typescript": "^7.16.0", | ||||
|     "@docsearch/css": "3.0.0-alpha.41", | ||||
|     "@docsearch/js": "3.0.0-alpha.41", | ||||
|  | ||||
| @ -1,3 +0,0 @@ | ||||
| const babelConfig = require('./cjs/babel.config.cjs'); | ||||
| 
 | ||||
| module.exports = (api, options) => babelConfig(api, options); | ||||
| @ -1,6 +1,6 @@ | ||||
| import fse from 'fs-extra'; | ||||
| import execa from 'execa'; | ||||
| import { join, relative } from 'path'; | ||||
| import fse from 'fs-extra'; | ||||
| import { clean } from './clean.js'; | ||||
| import { CSS_LANG } from '../common/css.js'; | ||||
| import { ora, consola } from '../common/logger.js'; | ||||
| @ -27,12 +27,13 @@ import { | ||||
|   setModuleEnv, | ||||
|   setBuildTarget, | ||||
| } from '../common/index.js'; | ||||
| import type { Format } from 'esbuild'; | ||||
| 
 | ||||
| const { remove, copy, readdir, existsSync } = fse; | ||||
| 
 | ||||
| async function compileFile(filePath: string) { | ||||
| async function compileFile(filePath: string, format: Format) { | ||||
|   if (isScript(filePath)) { | ||||
|     return compileScript(filePath); | ||||
|     return compileScript(filePath, format); | ||||
|   } | ||||
|   if (isStyle(filePath)) { | ||||
|     return compileStyle(filePath); | ||||
| @ -69,12 +70,14 @@ async function preCompileDir(dir: string) { | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| async function compileDir(dir: string) { | ||||
| async function compileDir(dir: string, format: Format) { | ||||
|   const files = await readdir(dir); | ||||
|   await Promise.all( | ||||
|     files.map((filename) => { | ||||
|       const filePath = join(dir, filename); | ||||
|       return isDir(filePath) ? compileDir(filePath) : compileFile(filePath); | ||||
|       return isDir(filePath) | ||||
|         ? compileDir(filePath, format) | ||||
|         : compileFile(filePath, format); | ||||
|     }) | ||||
|   ); | ||||
| } | ||||
| @ -86,13 +89,13 @@ async function copySourceCode() { | ||||
| async function buildESMOutputs() { | ||||
|   setModuleEnv('esmodule'); | ||||
|   setBuildTarget('package'); | ||||
|   await compileDir(ES_DIR); | ||||
|   await compileDir(ES_DIR, 'esm'); | ||||
| } | ||||
| 
 | ||||
| async function buildCJSOutputs() { | ||||
|   setModuleEnv('commonjs'); | ||||
|   setBuildTarget('package'); | ||||
|   await compileDir(LIB_DIR); | ||||
|   await compileDir(LIB_DIR, 'cjs'); | ||||
| } | ||||
| 
 | ||||
| async function buildTypeDeclarations() { | ||||
|  | ||||
| @ -14,6 +14,7 @@ export const TEST_REGEXP = new RegExp('\\' + sep + 'test$'); | ||||
| export const ASSET_REGEXP = /\.(png|jpe?g|gif|webp|ico|jfif|svg|woff2?|ttf)$/i; | ||||
| export const STYLE_REGEXP = /\.(css|less|scss)$/; | ||||
| export const SCRIPT_REGEXP = /\.(js|ts|jsx|tsx)$/; | ||||
| export const JSX_REGEXP = /\.(j|t)sx$/; | ||||
| export const ENTRY_EXTS = ['js', 'ts', 'tsx', 'jsx', 'vue']; | ||||
| 
 | ||||
| export function removeExt(path: string) { | ||||
| @ -46,33 +47,14 @@ export function getComponents() { | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| export function isDir(dir: string) { | ||||
|   return lstatSync(dir).isDirectory(); | ||||
| } | ||||
| 
 | ||||
| export function isDemoDir(dir: string) { | ||||
|   return DEMO_REGEXP.test(dir); | ||||
| } | ||||
| 
 | ||||
| export function isTestDir(dir: string) { | ||||
|   return TEST_REGEXP.test(dir); | ||||
| } | ||||
| 
 | ||||
| export function isAsset(path: string) { | ||||
|   return ASSET_REGEXP.test(path); | ||||
| } | ||||
| 
 | ||||
| export function isSfc(path: string) { | ||||
|   return SFC_REGEXP.test(path); | ||||
| } | ||||
| 
 | ||||
| export function isStyle(path: string) { | ||||
|   return STYLE_REGEXP.test(path); | ||||
| } | ||||
| 
 | ||||
| export function isScript(path: string) { | ||||
|   return SCRIPT_REGEXP.test(path); | ||||
| } | ||||
| export const isDir = (dir: string) => lstatSync(dir).isDirectory(); | ||||
| export const isDemoDir = (dir: string) => DEMO_REGEXP.test(dir); | ||||
| export const isTestDir = (dir: string) => TEST_REGEXP.test(dir); | ||||
| export const isAsset = (path: string) => ASSET_REGEXP.test(path); | ||||
| export const isSfc = (path: string) => SFC_REGEXP.test(path); | ||||
| export const isStyle = (path: string) => STYLE_REGEXP.test(path); | ||||
| export const isScript = (path: string) => SCRIPT_REGEXP.test(path); | ||||
| export const isJsx = (path: string) => JSX_REGEXP.test(path); | ||||
| 
 | ||||
| const camelizeRE = /-(\w)/g; | ||||
| const pascalizeRE = /(\w)(\w*)/g; | ||||
|  | ||||
| @ -1,16 +1,18 @@ | ||||
| import fse from 'fs-extra'; | ||||
| import babel from '@babel/core'; | ||||
| import esbuild, { type Format } from 'esbuild'; | ||||
| import { sep } from 'path'; | ||||
| import { transformAsync } from '@babel/core'; | ||||
| import { replaceExt } from '../common/index.js'; | ||||
| import { isJsx, replaceExt } from '../common/index.js'; | ||||
| import { replaceCSSImportExt } from '../common/css.js'; | ||||
| import { replaceScriptImportExt } from './get-deps.js'; | ||||
| 
 | ||||
| const { readFileSync, removeSync, outputFileSync } = fse; | ||||
| 
 | ||||
| export async function compileScript(filePath: string): Promise<void> { | ||||
|   return new Promise((resolve, reject) => { | ||||
| export async function compileScript( | ||||
|   filePath: string, | ||||
|   format: Format | ||||
| ): Promise<void> { | ||||
|   if (filePath.includes('.d.ts')) { | ||||
|       resolve(); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
| @ -21,16 +23,34 @@ export async function compileScript(filePath: string): Promise<void> { | ||||
|   } | ||||
|   code = replaceScriptImportExt(code, '.vue', ''); | ||||
| 
 | ||||
|     transformAsync(code, { filename: filePath }) | ||||
|       .then((result) => { | ||||
|         if (result) { | ||||
|           const jsFilePath = replaceExt(filePath, '.js'); | ||||
| 
 | ||||
|           removeSync(filePath); | ||||
|           outputFileSync(jsFilePath, result.code); | ||||
|           resolve(); | ||||
|         } | ||||
|       }) | ||||
|       .catch(reject); | ||||
|   if (isJsx(filePath)) { | ||||
|     const babelResult = await babel.transformAsync(code, { | ||||
|       filename: filePath, | ||||
|       babelrc: false, | ||||
|       presets: ['@babel/preset-typescript'], | ||||
|       plugins: [ | ||||
|         [ | ||||
|           '@vue/babel-plugin-jsx', | ||||
|           { | ||||
|             enableObjectSlots: false, | ||||
|           }, | ||||
|         ], | ||||
|       ], | ||||
|     }); | ||||
|     if (babelResult?.code) { | ||||
|       ({ code } = babelResult); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const esbuildResult = await esbuild.transform(code, { | ||||
|     loader: 'ts', | ||||
|     target: 'es2016', | ||||
|     format, | ||||
|   }); | ||||
| 
 | ||||
|   ({ code } = esbuildResult); | ||||
| 
 | ||||
|   const jsFilePath = replaceExt(filePath, '.js'); | ||||
|   removeSync(filePath); | ||||
|   outputFileSync(jsFilePath, code); | ||||
| } | ||||
|  | ||||
| @ -1,11 +0,0 @@ | ||||
| module.exports = { | ||||
|   presets: [ | ||||
|     [ | ||||
|       '@vant/cli/preset.cjs', | ||||
|       { | ||||
|         loose: process.env.BUILD_TARGET === 'package', | ||||
|         enableObjectSlots: false, | ||||
|       }, | ||||
|     ], | ||||
|   ], | ||||
| }; | ||||
							
								
								
									
										912
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										912
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user