Skip to content

Commit

Permalink
build: 公共依赖cdn解耦并增加开关控制 (#360)
Browse files Browse the repository at this point in the history
* build: external public cdn localize 公共cdn依赖包支持本地化

* build: cdn外部依赖解耦,修复baseUrl获取

* build: cdn依赖解耦 修正baseUrl获取方式

* build: cdn依赖三方解耦,优化目录型拷贝

* build: cdn依赖解耦,解决目录复制文件的相对路径问题

* build(design-core): 修复monaco的worker使用cdn地址前缀的情况下打包失效

* build: 本地开发也支持脱离cdn三方依赖

* build: 去除代码注释

* build: 三方cdn依赖解耦  物料bundle文件依赖支持替换cdn依赖

* build(design-core) 去除冗余用不到的文件和配置项硬编码

* build: 公共依赖cdn解耦测试完成 开关默认关闭

* refactor: 简化三方cdn依赖解耦的正则,改为path方法

* refactor: 三方依赖解耦脚本代码优化,减少雷同的正则匹配

* refactor: 三方cdn依赖解耦脚本 简化合并正则

* build: 三方cdn解耦 物料本地打包逻辑优化修正

* build: 三方cdn依赖解耦,优化代码简化正则,修复计算版本号问题,修复函数名大小写问题

* build: 优化importMap版本站位符号

* build: 三方cdn物料解耦 变量改为环境变量

* build: 三方cdn依赖解耦 补充处理复制文件夹时候的去重

* fix: 三方cdn解耦, 解决本地启动问题

* feat(preview): preview也支持cdn依赖解耦

* refactor(desing-core/scripts): 重构复制cdn文件本地复制模块

* build:  重构预览的importMap复制逻辑,修复两个importMap文件不存在

* build: 进一步优化monacoEditor地址,直接打包不再跨网络获取

* refactor(design-core/scripts): 调整复制应用importMap函数的参数顺序,与其他结构类似

* refactor(design-core/script): 调整文件位置和文件引用顺序

* feat(design-core/preview): preview importMap.js 使用 importMap.json 数据归一

* fix(design-core/preview): 修复importJson的引用

* fix: mock端口号订正,解决element-plus拖入画布后无法渲染

* build(design-core/script): 修复临时安装包插件安装完包后返回目录不正确

* fix: 修正monaco-editor的worker资源的打包地址

* build(design-core/script): 修复临时安装包插件安装完包后返回目录不正确

* fix(design-core/preview): 修正cdn解耦preview获取动态的importMap.json的base路径问题

* build: 三方cdn解耦,优化拷贝脚本,修复文件夹当文件拷贝当文件夹是包路径时候目标路径版本号丢失

* build: 三方cdn解耦,解决包未安装的情况下,glob匹配不到文件导致打包不拷贝内容

* fix: 根据检视意见使用fs-extra readJsonSync替代utils工具函数

* fix: 根据检视意见修改函数名大小写和端口号读取

* feat: 三方物料解耦 preview变量替换增加注释

* feat: 根据检视意见修改函数名字

* refactor: 根据检视意见,将脚本函数的参数整改为对象,并把目录值迁移到参数默认值

* docs(design-core/scripts): 三方cdn解耦 修正描述错误

* fix: 三方cdn解耦 修正preview脚本TinyVue版本号
  • Loading branch information
rhlin authored May 13, 2024
1 parent 3a66996 commit 899d616
Show file tree
Hide file tree
Showing 21 changed files with 721 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package-lock.json
yarn.lock
pnpm-lock.yaml
lerna-debug.log
packages/design-core/bundle-deps

# local env files
.env.local
Expand Down
23 changes: 12 additions & 11 deletions packages/canvas/src/components/common/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/**
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
* Copyright (c) 2023 - present TinyEngine Authors.
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/

export const NODE_UID = 'data-uid'
export const NODE_TAG = 'data-tag'
Expand Down Expand Up @@ -125,9 +125,10 @@ export const getClipboardSchema = (event) => translateStringToSchame(event.clipb
*/
export const dynamicImportComponents = async ({ package: pkg, script, components }) => {
if (!script) return
const scriptUrl = script.startsWith('.') ? new URL(script, location.href).href : script

if (!window.TinyComponentLibs[pkg]) {
const modules = await import(/* @vite-ignore */ script)
const modules = await import(/* @vite-ignore */ scriptUrl)

window.TinyComponentLibs[pkg] = modules
}
Expand Down
2 changes: 2 additions & 0 deletions packages/design-core/.env.alpha
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

NODE_ENV=production
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
VITE_LOCAL_IMPORT_MAPS=false
VITE_LOCAL_BUNDLE_DEPS=false
# VITE_ORIGIN=

# 错误监控上报 url
Expand Down
4 changes: 3 additions & 1 deletion packages/design-core/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

NODE_ENV=development
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
VITE_LOCAL_IMPORT_MAPS=false
VITE_LOCAL_BUNDLE_DEPS=false
# request data via alpha service
# VITE_ORIGIN=
# VITE_ORIGIN=
4 changes: 3 additions & 1 deletion packages/design-core/.env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

NODE_ENV=production
VITE_CDN_DOMAIN=https://npm.onmicrosoft.cn
#VITE_ORIGIN=
VITE_LOCAL_IMPORT_MAPS=false
VITE_LOCAL_BUNDLE_DEPS=false
#VITE_ORIGIN=
1 change: 0 additions & 1 deletion packages/design-core/canvas.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="%VITE_CDN_DOMAIN%/@opentiny/[email protected]/index.css" rel="stylesheet" />
<style type="text/css">
.loading-warp {
display: flex;
Expand Down
4 changes: 3 additions & 1 deletion packages/design-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@
"rollup-plugin-polyfill-node": "^0.12.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-visualizer": "^5.8.3",
"shelljs": "^0.8.5",
"svg-sprite-loader": "^6.0.11",
"vite": "^4.3.7",
"vite-plugin-monaco-editor": "^1.0.10",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-static-copy": "^0.16.0",
"vite-plugin-svg-icons": "^2.0.1",
"vue-eslint-parser": "^8.0.1"
},
Expand Down
82 changes: 82 additions & 0 deletions packages/design-core/scripts/localCdnFile/copyBundleDeps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import path from 'node:path'
import { readJsonSync } from 'fs-extra'
import { installPackageTemporary } from '../vite-plugins/installPackageTemporary'
import { configServerAddProxy } from '../vite-plugins/configureServerAddProxy'
import { viteStaticCopy } from 'vite-plugin-static-copy'
import {
getCdnPathNpmInfoForSingleFile,
getPackageNeedToInstallAndFilesUsingSameVersion,
dedupeCopyFiles,
copyfileToDynamicSrcMapper
} from './locateCdnNpmInfo'

export function extraBundleCdnLink(filename, originCdnPrefix) {
const result = []
const bundle = readJsonSync(filename)
bundle.data?.materials?.components?.forEach((component) => {
if (component.npm) {
const possibleUrl = [component.npm.script, component.npm.css]
possibleUrl.forEach((url) => {
if (url?.startsWith(originCdnPrefix) && !result.includes(url)) {
result.push(url)
}
})
}
})
return result
}

export function replaceBundleCdnLink(bundle, fileMap) {
bundle.data?.materials?.components?.forEach((component) => {
if (component.npm) {
const possibleUrl = ['script', 'css']
possibleUrl.forEach((key) => {
const matchRule = fileMap.find((rule) => component.npm[key] === rule.originUrl)
if (matchRule) {
component.npm[key] = matchRule.newUrl
}
})
}
})
}

export function copyBundleDeps({
bundleFile,
targetBundleFile,
originCdnPrefix,
base,
dir = 'material-static',
bundleTempDir = 'bundle-deps/material-static'
}) {
const cdnFiles = extraBundleCdnLink(bundleFile, originCdnPrefix).map((url) =>
getCdnPathNpmInfoForSingleFile(url, originCdnPrefix, base, dir, false, bundleTempDir)
)
const { packages: packageNeedToInstall, files } = getPackageNeedToInstallAndFilesUsingSameVersion(cdnFiles)

const plugin = (isDev) => {
return [
...(isDev ? configServerAddProxy(targetBundleFile, targetBundleFile.replace(/\.([^.]+?$)/, '-local.$1')) : []),
...installPackageTemporary(packageNeedToInstall, bundleTempDir),
...viteStaticCopy({
targets: [
...dedupeCopyFiles(files).map(copyfileToDynamicSrcMapper),
{
src: bundleFile,
dest: path.dirname(targetBundleFile),
transform: (content) => {
const json = JSON.parse(content)
replaceBundleCdnLink(json, files)
return JSON.stringify(json, null, 2)
},
rename: (filename, fileExtension) =>
isDev ? `${filename}-local.${fileExtension}` : path.basename(targetBundleFile),
overwrite: true // 覆盖public的
}
]
})
]
}
return {
plugin
}
}
67 changes: 67 additions & 0 deletions packages/design-core/scripts/localCdnFile/copyImportMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { viteStaticCopy } from 'vite-plugin-static-copy'
import {
getPackageNeedToInstallAndFilesUsingSameVersion,
copyfileToDynamicSrcMapper,
dedupeCopyFiles,
getCdnPathNpmInfoForPackage,
getCdnPathNpmInfoForSingleFile
} from './locateCdnNpmInfo'
import { importmapPlugin } from '../externalDeps'
import { installPackageTemporary } from '../vite-plugins/installPackageTemporary'

export const copyLocalImportMap = ({
importMap,
styleUrls,
originCdnPrefix,
base,
dir = 'import-map-static',
bundleTempDir = 'bundle-deps/design-core-import-map',
packageCopy = [] // 值为importMap的imports的左值 (非右值的地址上的包名)
}) => {
const importMapFiles = Object.entries(importMap.imports)
.filter(([_libKey, libPath]) => libPath.startsWith(originCdnPrefix))
.map(([libKey, libPath]) => {
if (packageCopy.includes(libKey)) {
return getCdnPathNpmInfoForPackage(libPath, originCdnPrefix, base, dir, true, bundleTempDir)
}
return getCdnPathNpmInfoForSingleFile(libPath, originCdnPrefix, base, dir, false, bundleTempDir)
})
const styleFiles = styleUrls
.filter((styleUrl) => styleUrl.startsWith(originCdnPrefix))
.map((url) => getCdnPathNpmInfoForSingleFile(url, originCdnPrefix, base, dir, false), bundleTempDir)

const { packages: packageNeedToInstall, files } = getPackageNeedToInstallAndFilesUsingSameVersion(
importMapFiles.concat(styleFiles)
)

return [
...installPackageTemporary(packageNeedToInstall, bundleTempDir),
...viteStaticCopy({
targets: dedupeCopyFiles(files).map(copyfileToDynamicSrcMapper)
}),
{
config(config, { command }) {
// 处理devAlias带CDN域名, 另外需要使得本地vue和importMap的vue是同一个实例
if (command === 'serve') {
config.resolve.alias = [
...config.resolve.alias,
{
find: /^vue$/,
replacement: `http://localhost:${config.server.port || 8080}/${
files.find(({ originUrl }) => importMap.imports.vue === originUrl).newUrl
}` // 实际端口号需要更具本地启动修改
}
]
}
}
},
importmapPlugin(
{
imports: Object.fromEntries(
Object.entries(importMap.imports).map(([k, v]) => [k, files.find((f) => f.originUrl === v)?.newUrl ?? v])
)
},
styleUrls.map((url) => styleFiles.find((f) => f.originUrl === url).newUrl ?? url)
)
]
}
82 changes: 82 additions & 0 deletions packages/design-core/scripts/localCdnFile/copyPreviewImportMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import path from 'node:path'
import { readJsonSync } from 'fs-extra'
import {
getPackageNeedToInstallAndFilesUsingSameVersion,
copyfileToDynamicSrcMapper,
dedupeCopyFiles,
getCdnPathNpmInfoForPackage,
getCdnPathNpmInfoForSingleFile
} from './locateCdnNpmInfo'
import { viteStaticCopy } from 'vite-plugin-static-copy'
import { installPackageTemporary } from '../vite-plugins/installPackageTemporary'

export function extraPreviewImport(filename, originCdnPrefix) {
const result = []
const importMap = readJsonSync(filename)
Object.entries(importMap.imports)?.forEach(([_key, location]) => {
const url = location.replace('${VITE_CDN_DOMAIN}', originCdnPrefix).replace('${opentinyVueVersion}', '~3.14')
if (url?.startsWith(originCdnPrefix) && !result.includes(url)) {
result.push(url)
}
})
return result
}

export function replacePreviewImport(importMap, fileMap, originCdnPrefix) {
return {
imports: Object.fromEntries(
Object.entries(importMap.imports)?.map(([key, location]) => {
// 这里的替换占位符规则等同于packages/design-core/src/preview/src/preview/importMap.js, 两边修改需要同步
const url = location.replace('${VITE_CDN_DOMAIN}', originCdnPrefix).replace('${opentinyVueVersion}', '~3.14')
const matchRule = fileMap.find((rule) => url === rule.originUrl)
if (matchRule) {
return [key, matchRule.newUrl]
}
return [key, location]
})
)
}
}

export function extraPreviewImportFile(filename, targetFileName, originCdnPrefix) {
return (fileMap) => [
{
src: filename,
dest: path.dirname(targetFileName),
transform: (content) => {
return JSON.stringify(replacePreviewImport(JSON.parse(content), fileMap, originCdnPrefix), null, 2)
},
rename: path.basename(targetFileName)
}
]
}

export function copyPreviewImportMap({
importMapJson,
targetImportMapJson,
originCdnPrefix,
base,
dir = 'preview-import-map-static',
bundleTempDir = 'bundle-deps/preview-import-map',
packageCopyLib = [] // 值为cdn地址上的包名
}) {
const cdnFiles = extraPreviewImport(importMapJson, originCdnPrefix).map((url) => {
const { packageName } = url.match(
new RegExp(`^${originCdnPrefix}/?(?<packageName>.+?)@(?<versionDemand>[^/]+)(?<filePathInPackage>.*?)$`)
).groups
if (packageCopyLib.includes(packageName)) {
return getCdnPathNpmInfoForPackage(url, originCdnPrefix, base, dir, true, bundleTempDir)
}
return getCdnPathNpmInfoForSingleFile(url, originCdnPrefix, base, dir, false, bundleTempDir)
})
const { packages: packageNeedToInstall, files } = getPackageNeedToInstallAndFilesUsingSameVersion(cdnFiles)
return [
...installPackageTemporary(packageNeedToInstall, bundleTempDir),
...viteStaticCopy({
targets: [
...dedupeCopyFiles(files).map(copyfileToDynamicSrcMapper),
...extraPreviewImportFile(importMapJson, targetImportMapJson, originCdnPrefix)(files)
]
})
]
}
6 changes: 6 additions & 0 deletions packages/design-core/scripts/localCdnFile/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './copyBundleDeps'
export * from './copyImportMap'
export * from './copyPreviewImportMap'
export * from './utils'
export * from './locateCdnNpmInfo'
export * from './replaceImportPath.mjs'
Loading

0 comments on commit 899d616

Please sign in to comment.