Skip to content

Commit

Permalink
feat: 支持配置正则移除模块引用
Browse files Browse the repository at this point in the history
  • Loading branch information
liuyue28 authored and harttle committed Jan 21, 2021
1 parent a91f552 commit b443052
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/compilers/renderer-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@ export interface RenderOptions {
functionName?: string
ssrOnly?: boolean
importHelpers?: string
/**
* 删除 ssr 不需要引入的模块,仅对 TypedSanSourceFile 有效
*/
removeModules?: RegExp[]
/**
* 不同 target 实现的 CompilerOptions 可以继承并扩充字段
*/
[key: string]: any;
}
9 changes: 8 additions & 1 deletion src/models/san-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { ComponentClassParser } from '../parsers/component-class-parser'
import { TypeScriptSanParser } from '../parsers/typescript-san-parser'
import { JavaScriptSanParser } from '../parsers/javascript-san-parser'
import { SanFileParser } from '../parsers/san-file-parser'
import { removeModules } from '../parsers/remove-modules'
import { TypedSanSourceFile, DynamicSanSourceFile, SanSourceFile } from '../models/san-source-file'
import ToJSCompiler from '../target-js/index'
import { CompileOptions } from '../target-js/compilers/compile-options'
import { RenderOptions } from '../compilers/renderer-options'
import { Renderer } from './renderer'
import { getDefaultTSConfigPath } from '../parsers/tsconfig'
import { Compiler } from '../models/compiler'
Expand Down Expand Up @@ -44,9 +46,14 @@ export class SanProject {
public compileToSource<T extends Compiler> (
input: CompileInput,
target: string | CompilerClass<T> = 'js',
options = {}
options: RenderOptions = {}
) {
const sanSourceFile = this.parseSanSourceFile(input)
// 删除配置中指定的在 ssr 下无需引入的模块
const { removeModules: modules } = options
if (modules && modules.length) {
removeModules(sanSourceFile, modules)
}
const compiler = this.getOrCreateCompilerInstance(target)
return compiler.compileToSource(sanSourceFile, options)
}
Expand Down
23 changes: 23 additions & 0 deletions src/parsers/remove-modules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { SanSourceFile, isTypedSanSourceFile } from '../models/san-source-file'
import debugFactory from 'debug'

const debug = debugFactory('san-ssr:remove-modules')

/**
* 删除模块引用
*/
export function removeModules (sanSourceFile: SanSourceFile, modules: RegExp[]) {
if (!isTypedSanSourceFile(sanSourceFile)) {
debug('TypedSanSourceFile is required')
return
}
const importDeclarations = sanSourceFile.tsSourceFile.getImportDeclarations()
debug('removing modules', importDeclarations)
importDeclarations.forEach(i => {
const specifierValue = i.getModuleSpecifierValue()
if (modules.some(re => re.test(specifierValue))) {
debug(`remove ${specifierValue}`)
i.remove()
}
})
}
12 changes: 12 additions & 0 deletions test/stub/remove-modules.comp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// <reference path="./remove-modules.d.ts"/>
import foo from 'foo'
import bar from 'bar'
import { Component } from 'san'

export default class RemoveModulesComp extends Component {
public static template = '<div>Remove foo</div>'
mounted () {
foo()
bar()
}
}
2 changes: 2 additions & 0 deletions test/stub/remove-modules.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
declare module 'foo'
declare module 'bar'
9 changes: 9 additions & 0 deletions test/unit/models/san-project.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ describe('SanProject', function () {
expect(render).toBeInstanceOf(Function)
expect(render({ name: 'Harttle' }, true)).toEqual('<div>name: Harttle</div>')
})

it('should remove modules', function () {
const proj = new SanProject()
const code = proj.compileToSource(resolve(stubRoot, './remove-modules.comp.ts'), 'js', {
removeModules: [/^foo/]
})
expect(code).not.toContain('require("foo")')
expect(code).toContain('require("bar")')
})
})
describe('.loadCompilerClassByTarget()', () => {
let proj: SanProject
Expand Down
26 changes: 26 additions & 0 deletions test/unit/parsers/remove-modules.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { removeModules } from '../../../src/parsers/remove-modules'
import { TypedSanSourceFile } from '../../../src/models/san-source-file'
import { SanProject } from '../../../src/models/san-project'
import { resolve } from 'path'

const testRoot = resolve(__dirname, '../../')
const stubRoot = resolve(testRoot, 'stub')

const mockDebug = jest.fn()
jest.mock('debug', () => () => (str: string) => mockDebug(str))

describe('removeModules', () => {
it('should deal with TypedSanSourceFile only', () => {
const proj = new SanProject()
const sanSourceFile = proj.parseSanSourceFile(resolve(stubRoot, './a.comp.js'))
removeModules(sanSourceFile, [])
expect(mockDebug).toHaveBeenCalledWith('TypedSanSourceFile is required')
})

it('should remove modules', () => {
const proj = new SanProject(resolve(testRoot, '../tsconfig.json'))
const sanSourceFile = proj.parseSanSourceFile(resolve(stubRoot, './remove-modules.comp.ts')) as TypedSanSourceFile
removeModules(sanSourceFile, [/^foo/])
expect(sanSourceFile.tsSourceFile.getImportDeclaration('foo')).toBeUndefined()
})
})

0 comments on commit b443052

Please sign in to comment.