Skip to content

Commit

Permalink
feat(plugin-compiler-web): 完善小程序转 Web 的功能逻辑以及禁止载入用户自定义的 babel 配置
Browse files Browse the repository at this point in the history
  • Loading branch information
lyfeyaj committed Jul 10, 2023
1 parent 0b4d3ab commit 824e032
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default class DataBinding implements DataBindingNode {
res = this.parseExp(code)
// 再次提取变量
if (!res.isOK) {
logger.error(`绑定表达式: ${code.trim()} 不符合JS表达式规范`)
logger.error(`绑定表达式: ${code.trim()} 不符合 JS 表达式规范`)
}
}
if (res.code) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ export default function (document: Document, options: AXMLOptions) {
const result = generate.default(ast)
if (options.isAtomicMode && !options.unitTest) {
return babel.transformSync(result.code, {
configFile: false,
babelrc: false,
presets: [require(resolveDependency('@babel/preset-react'))]
}).code
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export function getOptionalChainCode(code) {
})

const source = babel.transformSync(result, {
configFile: false,
babelrc: false,
plugins: [
{
visitor: {
Expand Down
9 changes: 8 additions & 1 deletion packages/plugin-compiler-web/src/compiler/core/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,26 @@ export default function (content, options: BuildOptions) {

function transformFromCode(code: string, plugins, options: BuildOptions) {
let ast = babel.parse(code, {
configFile: false,
babelrc: false
// plugins: [require(resolveDependency('@babel/plugin-transform-react-jsx')), require(resolveDependency('@babel/plugin-proposal-class-properties'))]
})
const newCode = skipConditionalCompilation(code, ast, options)
if (newCode.length !== code.length) {
code = newCode
// 重新生成ast
ast = babel.parse(code)
ast = babel.parse(code, {
configFile: false,
babelrc: false
})
}

const babelConfig = {
compact: false,
generatorOpts: { comments: false },
ast: true,
configFile: false,
babelrc: false,
plugins
}

Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-compiler-web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EmitIntermediateAssetsPlugin } from './plugins/emitIntermediateAssetsPl
import { ExtractOrInjectCssPlugin } from './plugins/extractOrInjectCssPlugin'
import { GenerateJSXEntryPlugin } from './plugins/generateJSXEntryPlugin'
import { HtmlSupportPlugin } from './plugins/htmlSupportPlugin'
import { ScriptCompatiblePlugin } from './plugins/scriptCompatiblePlugin'
import { SjsCompatiblePlugin } from './plugins/sjsCompatiblePlugin'
import { TemplateCompatiblePlugin } from './plugins/templateCompatiblePlugin'

Expand Down Expand Up @@ -92,6 +93,7 @@ class WebCompilerPlugin implements MorPlugin {
new SjsCompatiblePlugin().apply(runner)
new TemplateCompatiblePlugin(entryBuilder).apply(runner)
new ConfigCompatiblePlugin(entryBuilder).apply(runner)
new ScriptCompatiblePlugin().apply(runner)

// bundle 模式适配
if (compileMode === 'bundle') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,18 @@ export class CommonConfigPlugin implements Plugin {
const BABEL_LOADER = {
loader: resolveDependency('babel-loader'),
options: {
configFile: false,
babelrc: false,
compact: false,
sourceType: 'unambiguous',
// 配置 targets 以保证低版本浏览器的兼容性
presets: [
[require(resolveDependency('@babel/preset-env')), babelEnvOptions],
require(resolveDependency('@babel/preset-react'))
[
require(resolveDependency('@babel/preset-react')),
// 允许一些错误的 namespace 存在
{ throwIfNamespace: false }
]
],
plugins: [
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export class EmitIntermediateAssetsPlugin implements Plugin {
command
) {
if (command.options?.emitWebIntermediateAssets) {
if (userConfig.target === target) {
const currentTarget = command.options?.target || userConfig.target
if (currentTarget === target) {
userConfig.web = userConfig.web || {}
userConfig.web.emitIntermediateAssets =
command.options.emitWebIntermediateAssets
Expand Down
48 changes: 26 additions & 22 deletions packages/plugin-compiler-web/src/plugins/scriptCompatiblePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
EntryFileType,
EntryType,
logger,
Plugin,
Runner,
} from '@morjs/utils'
import { EntryFileType, EntryType, logger, Plugin, Runner } from '@morjs/utils'
import path from 'path'

const EXPORT_DEFAULT_REGEXP = /export +default/
Expand All @@ -16,22 +10,32 @@ const EXPORT_DEFAULT_REGEXP = /export +default/
export class ScriptCompatiblePlugin implements Plugin {
name = 'MorWebScriptCompatiblePlugin'
apply(runner: Runner<any>) {
runner.hooks.preprocessorParser.tap(this.name, (content, context, options) => {
if (
options.fileInfo.entryFileType === EntryFileType.script && (
options.fileInfo.entryType === EntryType.page ||
options.fileInfo.entryType === EntryType.component ||
options.fileInfo.entryType === EntryType.npmComponent
)
) {
if (EXPORT_DEFAULT_REGEXP.test(content)) {
const filePath = path.relative(runner.getCwd(), options.fileInfo.path)
logger.warnOnce(`文件: ${filePath} 中使用了 export default\n` + `该导出方式为 MorJS 转 Web 页面或组件的标准导出方式,已自动移除`)
return content.replace(EXPORT_DEFAULT_REGEXP, '')
runner.hooks.preprocessorParser.tap(
this.name,
(content, context, options) => {
if (
options.fileInfo.entryFileType === EntryFileType.script &&
(options.fileInfo.entryType === EntryType.page ||
options.fileInfo.entryType === EntryType.component ||
options.fileInfo.entryType === EntryType.npmComponent)
) {
// NOTE: 这里的移除方式相对比较粗暴,后续可以考虑换位 ts 插件来处理
if (EXPORT_DEFAULT_REGEXP.test(content)) {
const filePath = path.relative(
runner.getCwd(),
options.fileInfo.path
)
logger.warnOnce(
`已自动移除组件或页面的 export default 导出\n` +
`原因: 该导出方式为 MorJS 转 Web 页面或组件的标准导出方式\n` +
`文件: ${filePath}`
)
return content.replace(EXPORT_DEFAULT_REGEXP, '')
}
}
}

return content
})
return content
}
)
}
}
120 changes: 78 additions & 42 deletions packages/plugin-compiler-web/src/plugins/templateCompatiblePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sjsSrcAttrName, sjsTagName } from '@morjs/plugin-compiler-alipay'
import {
EntryBuilderHelpers,
logger,
Expand All @@ -17,57 +18,92 @@ export class TemplateCompatiblePlugin implements Plugin {
name = 'MorWebTemplateCompatiblePlugin'
constructor(public entryBuilder: EntryBuilderHelpers) {}
apply(runner: Runner<any>) {
const entryBuilder = this.entryBuilder
function transformFilePath(importPath: string, requestPath: string) {
const realPath = entryBuilder.getFullPathOfReferenceFile(
requestPath,
importPath
)

if (realPath) {
let relativePath = path.relative(path.dirname(requestPath), realPath)
relativePath = slash(
relativePath.startsWith('.') ? relativePath : './' + relativePath
)
return relativePath
} else {
return importPath
}
}
// 替换 模版和 sjs 为正确的路径
// 将文件纬度条件编译的结果应用到文件本身
// NOTE: sjs 引用路径需要支持替换
runner.hooks.templateParser.tap(this.name, (tree, options) => {
const entryBuilder = this.entryBuilder

return tree.walk((node) => {
if (node.tag === 'import' || node.tag === 'include') {
if (
node.attrs &&
node.attrs.src &&
typeof node.attrs.src === 'string'
) {
const importPath = node.attrs.src
const realPath = entryBuilder.getFullPathOfReferenceFile(
options.fileInfo.path,
importPath
)
runner.hooks.templateParser.tap(
{
name: this.name,
stage: 0
},
(tree, options) => {
return tree.walk((node) => {
// 移除所有的注释
if (node.content?.length) {
node.content = node.content.filter((content) => {
if (
typeof content === 'string' &&
content.trim().startsWith('<!--')
) {
return false
}
return true
})
}

if (realPath) {
let relativePath = path.relative(
path.dirname(options.fileInfo.path),
realPath
if (node.tag === 'import' || node.tag === 'include') {
if (
node.attrs &&
node.attrs.src &&
typeof node.attrs.src === 'string'
) {
node.attrs.src = transformFilePath(
node.attrs.src,
options.fileInfo.path
)
relativePath = slash(
relativePath.startsWith('.')
? relativePath
: './' + relativePath
)
node.attrs.src = relativePath
} else {
node.attrs.src = importPath
logger.warn(
'import/include 标签需要设置 src 属性' +
`文件路径: ${options.fileInfo.path}`
)
}
} else if (node.tag === 'image') {
if (
node.attrs &&
node.attrs.src &&
typeof node.attrs.src === 'string'
) {
node.attrs.src = getRelativePath(node.attrs.src)
}
} else {
logger.warn(
'import/include 标签需要设置 src 属性' +
`文件路径: ${options.fileInfo.path}`
)
}
} else if (node.tag === 'image') {
if (
node.attrs &&
node.attrs.src &&
typeof node.attrs.src === 'string'
) {
node.attrs.src = getRelativePath(node.attrs.src)
// sjs 支持
else if (node.tag === sjsTagName || node.tag === 'wxs') {
// 支付宝 DSL 兼容
if (node.attrs?.[sjsSrcAttrName]) {
node.attrs[sjsSrcAttrName] = transformFilePath(
node.attrs[sjsSrcAttrName],
options.fileInfo.path
)
}
// 微信 DSL 兼容
if (node.attrs?.['src']) {
node.attrs['src'] = transformFilePath(
node.attrs['src'],
options.fileInfo.path
)
}
}
}

return node
})
})
return node
})
}
)
}
}

0 comments on commit 824e032

Please sign in to comment.