提交 2e0a8f96 编写于 作者: fxy060608's avatar fxy060608

wip(app): confusion

上级 33152153
......@@ -18,6 +18,7 @@ import { uniPagesJsonPlugin } from './plugins/pagesJson'
import { uniRenderjsPlugin } from './plugins/renderjs'
import { uniStatsPlugin } from './plugins/stats'
import { uniEasycomPlugin } from './plugins/easycom'
import { uniConfusionPlugin } from './plugins/confusion'
function initUniCssScopedPluginOptions() {
const styleIsolation = getAppStyleIsolation(
......@@ -54,6 +55,7 @@ const plugins = [
uniTemplatePlugin(),
uniStatsPlugin(),
uniAppPlugin(),
uniConfusionPlugin(),
]
const uniCssScopedPluginOptions = initUniCssScopedPluginOptions()
......
......@@ -5,9 +5,8 @@ import { ConfigEnv, UserConfig } from 'vite'
import {
emptyDir,
normalizePath,
isConfusionFile,
hasConfusionFile,
resolveMainPathOnce,
APP_SERVICE_FILENAME,
} from '@dcloudio/uni-cli-shared'
export function buildOptions(configEnv: ConfigEnv): UserConfig['build'] {
......@@ -22,7 +21,7 @@ export function buildOptions(configEnv: ConfigEnv): UserConfig['build'] {
emptyOutDir: false, // 不清空输出目录,否则会影响 webpack 的输出
assetsInlineLimit: 0,
rollupOptions: {
input: resolveMainPathOnce(process.env.UNI_INPUT_DIR),
input: resolveMainPathOnce(inputDir),
external: ['vue'],
output: {
name: 'AppService',
......@@ -30,7 +29,7 @@ export function buildOptions(configEnv: ConfigEnv): UserConfig['build'] {
amd: {
autoId: true,
},
entryFileNames: 'app-service.js',
entryFileNames: APP_SERVICE_FILENAME,
sourcemapPathTransform(relativeSourcePath, sourcemapPath) {
const sourcePath = normalizePath(
path.relative(
......@@ -43,22 +42,10 @@ export function buildOptions(configEnv: ConfigEnv): UserConfig['build'] {
}
return 'uni-app:///' + sourcePath
},
manualChunks(id) {
if (hasConfusionFile()) {
if (
configEnv.mode === 'production' &&
isConfusionFile(path.relative(inputDir, id))
) {
return 'app-confusion'
}
}
},
manualChunks: {},
chunkFileNames(chunk) {
if (chunk.isDynamicEntry && chunk.facadeModuleId) {
const filepath = path.relative(
process.env.UNI_INPUT_DIR,
chunk.facadeModuleId
)
const filepath = path.relative(inputDir, chunk.facadeModuleId)
return normalizePath(
filepath.replace(path.extname(filepath), '.js')
)
......
import path from 'path'
import { Plugin } from 'vite'
import {
APP_CONFUSION_FILENAME,
APP_SERVICE_FILENAME,
hasConfusionFile,
isConfusionFile,
removeExt,
} from '@dcloudio/uni-cli-shared'
import { OutputChunk } from 'rollup'
export function uniConfusionPlugin(): Plugin {
const inputDir = process.env.UNI_INPUT_DIR
const hasConfusion =
process.env.NODE_ENV === 'production' && hasConfusionFile(inputDir)
return {
name: 'vite:uni-app-confusion',
enforce: 'post',
apply: 'build',
config() {
if (!hasConfusion) {
return
}
return {
build: {
rollupOptions: {
output: {
format: process.env.UNI_APP_CODE_SPLITING ? 'amd' : 'cjs',
manualChunks(id) {
if (isConfusionFile(path.relative(inputDir, id))) {
return removeExt(APP_CONFUSION_FILENAME)
}
},
},
},
},
}
},
generateBundle(_, bundle) {
if (!hasConfusion) {
return
}
const appConfusionChunk = bundle[APP_CONFUSION_FILENAME] as OutputChunk
if (!appConfusionChunk) {
return
}
appConfusionChunk.code = wrapperAppConfusionCode(appConfusionChunk.code)
const appServiceChunk = bundle[APP_SERVICE_FILENAME] as OutputChunk
if (!appServiceChunk) {
return
}
appServiceChunk.code = wrapperAppServiceCode(appServiceChunk.code)
},
}
}
function replaceRequireVueCode(code: string) {
return code.replace(/require\(['"]vue['"]\)/gi, `$cjs_require$('vue')`)
}
function replaceRequireAppConfusionCode(code: string) {
return code.replace(
new RegExp(`require\\(['"].\\/${APP_CONFUSION_FILENAME}['"]\\)`, 'gi'),
`$cjs_require$('./${APP_CONFUSION_FILENAME}')`
)
}
function wrapperAppServiceCode(code: string) {
return replaceRequireAppConfusionCode(replaceRequireVueCode(code))
}
function wrapperAppConfusionCode(code: string) {
return `function $cjs_require$(name){if(name==='vue'){return Vue;}if(name==='./${APP_CONFUSION_FILENAME}'){return $appConfusion$;}};const $appConfusion$ = {};(function(exports){${replaceRequireVueCode(
code
)}})($appConfusion$);
`
}
......@@ -38,6 +38,7 @@
"loader-utils": "^1.1.0",
"lru-cache": "^4.1.2",
"merge-source-map": "^1.1.0",
"module-alias": "^2.2.2",
"postcss": "^8.3.8",
"postcss-comment": "^2.0.0",
"postcss-import": "^14.0.2",
......
......@@ -37,6 +37,8 @@
"jsonc-parser": "^3.0.0",
"magic-string": "^0.25.7",
"merge": "^2.1.1",
"mime": "^3.0.0",
"module-alias": "^2.2.2",
"postcss-import": "^14.0.2",
"postcss-load-config": "^3.1.0",
"postcss-selector-parser": "^6.0.6",
......@@ -48,6 +50,7 @@
"devDependencies": {
"@types/hash-sum": "^1.0.0",
"@types/less": "^3.0.3",
"@types/mime": "^2.0.3",
"@types/stylus": "^0.48.36",
"@vue/compiler-sfc": "3.2.21",
"postcss": "^8.3.8"
......
......@@ -6,6 +6,8 @@ export const EXTNAME_JS_RE = /\.[jt]sx?$/
export const ASSETS_INLINE_LIMIT = 40 * 1024
export const APP_SERVICE_FILENAME = 'app-service.js'
export const BINDING_COMPONENTS = '__BINDING_COMPONENTS__'
// APP 平台解析页面后缀的优先级
export const PAGE_EXTNAME_APP = ['.nvue', '.vue', '.tsx', '.jsx', '.js']
......
import path from 'path'
import { normalizePath } from '../../../utils'
import { EXTNAME_JS_RE } from '../../../constants'
import { parseManifestJsonOnce } from '../../manifest'
function isJsFile(filename: string) {
return EXTNAME_JS_RE.test(filename)
......@@ -16,26 +17,27 @@ function isStaticJsFile(filename: string) {
const dynamicConfusionJsFiles: string[] = []
export const APP_CONFUSION_FILENAME = 'app-confusion.js'
export function isConfusionFile(filename: string) {
return dynamicConfusionJsFiles.includes(normalizePath(filename))
}
export function hasConfusionFile() {
export function hasConfusionFile(inputDir?: string) {
if (inputDir) {
const manifestJson = parseManifestJsonOnce(inputDir)
const resources = manifestJson['app-plus']?.confusion?.resources
if (resources && parseConfusion(resources)[1].length) {
return true
}
}
return !!dynamicConfusionJsFiles.length
}
export function initConfusion(manifestJson: Record<string, any>) {
dynamicConfusionJsFiles.length = 0
if (!manifestJson.plus.confusion?.resources) {
return
}
const resources = manifestJson.plus.confusion.resources as Record<
string,
string
>
manifestJson.plus.confusion.resources = Object.keys(resources).reduce<
Record<string, string>
>((res, name) => {
function parseConfusion(resources: Record<string, unknown>) {
const res: Record<string, unknown> = {}
const dynamicJsFiles: string[] = []
Object.keys(resources).reduce<Record<string, unknown>>((res, name) => {
const extname = path.extname(name)
if (extname === '.nvue') {
res[name.replace('.nvue', '.js')] = resources[name]
......@@ -45,15 +47,30 @@ export function initConfusion(manifestJson: Record<string, any>) {
res[name] = resources[name]
} else {
// 非静态 js 将被合并进 app-confusion.js
dynamicConfusionJsFiles.push(name)
dynamicJsFiles.push(name)
}
} else {
throw new Error(`原生混淆仅支持 nvue 页面,错误的页面路径:${name}`)
}
// TODO 旧编译器会检查要加密的 nvue 页面(包括subnvue)是否被使用?后续有时间再考虑支持吧,意义不太大
return res
}, {})
if (dynamicConfusionJsFiles.length) {
manifestJson.plus.confusion.resources['app-confusion.js'] = {}
}, res)
if (dynamicJsFiles.length) {
res[APP_CONFUSION_FILENAME] = {}
}
return [res, dynamicJsFiles] as const
}
export function initConfusion(manifestJson: Record<string, any>) {
dynamicConfusionJsFiles.length = 0
if (!manifestJson.plus.confusion?.resources) {
return
}
const resources = manifestJson.plus.confusion.resources as Record<
string,
unknown
>
const [res, dynamicJsFiles] = parseConfusion(resources)
manifestJson.plus.confusion.resources = res
dynamicConfusionJsFiles.push(...dynamicJsFiles)
}
......@@ -38,7 +38,11 @@ export function normalizeAppManifestJson(
}
export * from './env'
export { isConfusionFile, hasConfusionFile } from './confusion'
export {
APP_CONFUSION_FILENAME,
isConfusionFile,
hasConfusionFile,
} from './confusion'
export {
getNVueCompiler,
getNVueStyleCompiler,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册