Skip to content

Commit

Permalink
feat: using babel replace magicString (#10)
Browse files Browse the repository at this point in the history
* faet: quque support catch error

* perf: improve vm logic

* perf: vm logic

* chore: clean code

* perf: inject script performance

* test: make test happy

* feat: init code-gen

* chore: add docs

* fix(vm): should work with catch branch

* refactor(code-gen): import & indentifier

* refactor: init export rewrite

* feat: complete exports node

* feat(code-gen): insert new line

* feat: named exports

* feat: migrate to babel

* test: add e2e

* chore: fix ci

* chore: e2e run with windows

* chore: fix ci

* chore: clean code

* feat: complete duplicated node remove

* fix: transform scope

* chore: clean code
  • Loading branch information
nonzzz committed Jul 11, 2023
1 parent 5e50728 commit a7c2f1a
Show file tree
Hide file tree
Showing 56 changed files with 2,448 additions and 1,068 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: E2e test

on: [push, pull_request]

jobs:
run-e2e-test:
strategy:
matrix:
version: [16, 18]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
with:
node-version: ${{ matrix.version }}

- name: install dependices
run: yarn

- name: build project
run: yarn build

- name: prepare e2e
run: yarn prepare:e2e

- name: run e2e test
run: yarn e2e
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
run: npm run build

- name: Run Test
run: npm run coverage
run: npm run test

- name: Report Coverage
uses: codecov/codecov-action@v2
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.12.1
63 changes: 0 additions & 63 deletions Architecture.md

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export interface CDNPluginOptions {
*auto will read the package.json has unpkg or jsdelivr path. If not willn't be
* repalce. set false you can define spare for each module.
*/
mode?: PresetDomain
url?: string
include?: FilterPattern
exclude?: FilterPattern
/**
Expand Down
183 changes: 183 additions & 0 deletions __tests__/code-gen.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import test from 'ava'
import { parse, traverse } from '@babel/core'
import { createCodeGenerator } from '../dist/code-gen'
import { createScanner } from '../dist/scanner'
import type { ModuleInfo } from '../src/interface'


test('filter', async (t) => {
const code = `
import { ref } from 'vue';
const v = ref(0)
`
const dependencies:Map<string, ModuleInfo> = new Map()
const codeGen = createCodeGenerator()
dependencies.set('vue', {
name: 'vue',
global: 'Vue',
version: '0.0.0',
relativeModule: '',
bindings: new Set()
})
codeGen.injectDependencies(dependencies)
t.is(codeGen.filter(code, 'mock.js'), true)
})

test('scope', async (t) => {
const code = 'import { version } from \'vue\';\n console.log(version);\n function t() { const version = 3;\n console.log(version) }'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'console.log(Vue.version);\nfunction t() {\n const version = 3;\n console.log(version);\n}')
})

test('exports loose source', async (t) => {
const code = 'import { version } from \'vue\';\n export { version };\n'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'export const version = Vue.version;')
})

test('exports loose source and re named exported name', async (t) => {
const code = 'import { version } from \'vue\';\n export { version, version as default };\n'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'export const version = Vue.version;\nexport default Vue.version;')
})

test('exports loose source and export self module', async (t) => {
const code = 'import { version , ref } from \'vue\';\n const t = \'nonzzz\';\n export { t, version, ref as default };'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'const t = \'nonzzz\';\nexport { t };\nconst version = Vue.version;\nexport default Vue.ref;')
})

test('exports with source', async (t) => {
const code = 'export { ref , version } from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'export const ref = Vue.ref,\n version = Vue.version;')
})

test('exports with source and re named local name', async (t) => {
const code = 'export { default as myVue, version } from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
if (!res.code) return
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ast = await parse(res.code, { babelrc: false, configFile: false })!
const keys:Set<string> = new Set()
await traverse(ast, {
ObjectProperty: {
enter: (path) => {
path.node.key.type === 'Identifier' && keys.add(path.node.key.name)
}
}
})
t.is(keys.size, scanner.dependencies.get('vue').bindings.size)
})

test('exports with source and re named exported name', async (t) => {
const code = 'export { version as default , ref } from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'export const ref = Vue.ref;\nexport default Vue.version;')
})

test('export all with source and re named it with default', async (t) => {
const code = 'export * as default from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
if (!res.code) return
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ast = await parse(res.code, { babelrc: false, configFile: false })!
const keys:Set<string> = new Set()
await traverse(ast, {
ObjectProperty: (path) => {
path.node.key.type === 'Identifier' && keys.add(path.node.key.name)
}
})
t.is(keys.size, scanner.dependencies.get('vue').bindings.size)
})

test('export all with source and re named it with custom', async (t) => {
const code = 'export * as myVue from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
if (!res.code) return
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ast = await parse(res.code, { babelrc: false, configFile: false })!
const keys:Set<string> = new Set()
await traverse(ast, {
ObjectProperty: (path) => {
path.node.key.type === 'Identifier' && keys.add(path.node.key.name)
}
})
t.is(keys.size, scanner.dependencies.get('vue').bindings.size)
})

test('export all declaration', async (t) => {
const code = 'export * from \'vue\''
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
if (!res.code) return
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const ast = await parse(res.code, { babelrc: false, configFile: false })!
let size = 0
await traverse(ast, {
VariableDeclarator: () => {
size++
}
})
t.is(size, scanner.dependencies.get('vue').bindings.size)
})

test('export with declaration', async (t) => {
const code = 'import { ref } from \'vue\';\nexport const value = ref(0);'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(res.code, 'export const value = Vue.ref(0);')
})


test('export all module but the current module itself contains duplicated node', async (t) => {
const code = 'export * from \'vue\';\nexport const version = \'self\';'
const scanner = createScanner(['vue'])
await scanner.scanAllDependencies()
const codeGen = createCodeGenerator()
codeGen.injectDependencies(scanner.dependencies)
const res = await codeGen.transform(code)
t.is(/'self'/.test(res.code), true)
})
3 changes: 0 additions & 3 deletions __tests__/fixtures/exporter/exports.js

This file was deleted.

13 changes: 0 additions & 13 deletions __tests__/fixtures/exporter/index.html

This file was deleted.

14 changes: 0 additions & 14 deletions __tests__/fixtures/exporter/main.js

This file was deleted.

13 changes: 0 additions & 13 deletions __tests__/fixtures/importer/index.html

This file was deleted.

17 changes: 0 additions & 17 deletions __tests__/fixtures/importer/main.js

This file was deleted.

14 changes: 0 additions & 14 deletions __tests__/fixtures/name-export/exports.js

This file was deleted.

7 changes: 0 additions & 7 deletions __tests__/fixtures/name-export/main.js

This file was deleted.

Loading

0 comments on commit a7c2f1a

Please sign in to comment.