From afba23565d713f1ef79e2e916be0263b9862196b Mon Sep 17 00:00:00 2001 From: icebox1234 <464752812@qq.com> Date: Sat, 29 Oct 2022 15:18:18 +0800 Subject: [PATCH 1/4] feat: homework --- .github/workflows/node.js.yml | 1 + .gitignore | 2 +- package.json | 3 +- src/components/__tests__/HelloWorld.spec.js | 4 +- src/mini-renderer.js | 74 ------------ src/mini-renderer.ts | 122 ++++++++++++++++++++ 6 files changed, 128 insertions(+), 78 deletions(-) delete mode 100644 src/mini-renderer.js create mode 100644 src/mini-renderer.ts diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index e581942..66f9635 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,5 +26,6 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm i + - run: npm tsc # Just run tests once - run: npm test \ No newline at end of file diff --git a/.gitignore b/.gitignore index edf1c43..183d3b3 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,4 @@ coverage *.njsproj *.sln *.sw? -mini-renderer2.js \ No newline at end of file +src/mini-renderer.js \ No newline at end of file diff --git a/package.json b/package.json index f777d4e..b984a5d 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "dev": "vite", "build": "vite build", "preview": "vite preview --port 4173", - "test": "vitest --environment jsdom" + "test": "vitest --environment jsdom", + "tsc":"tsc src/mini-renderer.ts --target esnext" }, "dependencies": { "vue": "^3.2.38" diff --git a/src/components/__tests__/HelloWorld.spec.js b/src/components/__tests__/HelloWorld.spec.js index a71f7a8..430d6ae 100644 --- a/src/components/__tests__/HelloWorld.spec.js +++ b/src/components/__tests__/HelloWorld.spec.js @@ -1,12 +1,12 @@ import { describe, it, expect } from 'vitest' -import { createApp } from '../../mini-renderer' +import { createApp } from '../../mini-renderer.js' import App from '../../App.vue' describe('createApp for dom', () => { it('should render component', () => { const app = createApp(App) app.mount(document.createElement('div')) - expect(app._component).not.toBe(App) + expect(app._component).not.toBe(App); }) it('should not mutate original root component options object', () => { diff --git a/src/mini-renderer.js b/src/mini-renderer.js deleted file mode 100644 index 874573b..0000000 --- a/src/mini-renderer.js +++ /dev/null @@ -1,74 +0,0 @@ -import { createRenderer } from '@vue/runtime-core' - -const render = createRenderer({ - forcePatchProp(el, key){ - return false - }, - patchProp( - el, - key, - prevValue, - nextValue, - isSVG = false, - prevChildren, - parentComponent, - parentSuspense, - unmountChildren - ){ - if(key.startsWith('on')) { - el.addEventListener(key.substr(2).toLowerCase(), nextValue) - } else { - el.setAttribute(key, nextValue) - } - }, - insert(child, parent, anchor){ - parent.insertBefore(child, anchor || null) - }, - remove(child){ - const parent = child.parentNode - if(parent) { - parent.removeNode(child) - } - }, - createElement(type, isSvg, isCustomizedBuiltIn){ - return document.createElement(type) - }, - createText(text){ - return document.createTextNode(text) - }, - createComment(text){ - return document.createComment(text) - }, - setText(node, text){ - node.nodeValue = text - }, - setElementText(el, text){ - el.textContent = text - }, - parentNode(node){ - return node.parentNode - }, - nextSibling(node){ - return node.nextSibling - }, - querySelector(selector){ - return document.querySelector(selector) - }, - setScopeId(el, id){ - el.setAttribute(id, '') - }, - cloneNode(el){ - return el.cloneNode(true) - }, - insertStaticContent(){ - return [] - } -}) - -const createApp = (...args) => { - //TODO -} - -export { - createApp -} diff --git a/src/mini-renderer.ts b/src/mini-renderer.ts new file mode 100644 index 0000000..f535905 --- /dev/null +++ b/src/mini-renderer.ts @@ -0,0 +1,122 @@ +import { + createRenderer, + RendererOptions, + ConcreteComponent, + createVNode, + AppContext, +} from '@vue/runtime-core' + + +const render = createRenderer({ + forcePatchProp(el, key): boolean { + return false + }, + patchProp( + el, + key, + prevValue, + nextValue, + isSVG = false, + prevChildren, + parentComponent, + parentSuspense, + unmountChildren + ) { + if (key.startsWith('on')) { + el.addEventListener(key.substring(2).toLowerCase(), nextValue) + } else { + el.setAttribute(key, nextValue) + } + }, + insert(child, parent, anchor) { + parent.insertBefore(child, anchor || null) + }, + remove(child) { + const parent = child.parentNode + if (parent) { + parent.removeNode(child) + } + }, + createElement(type, isSvg, isCustomizedBuiltIn) { + return document.createElement(type) + }, + createText(text) { + return document.createTextNode(text) + }, + createComment(text) { + return document.createComment(text) + }, + setText(node, text) { + node.nodeValue = text + }, + setElementText(el, text) { + el.textContent = text + }, + parentNode(node) { + return node.parentNode + }, + nextSibling(node) { + return node.nextSibling + }, + querySelector(selector) { + return document.querySelector(selector) + }, + setScopeId(el, id) { + el.setAttribute(id, '') + }, + cloneNode(el) { + return el.cloneNode(true) + }, + insertStaticContent(): any { + return [] + } +} as RendererOptions & { forcePatchProp?: (el: any, key: string) => boolean }) + +function createAppContext(): AppContext { + return { + app: null as any, + config: { + isNativeTag: () => false, + performance: false, + globalProperties: {}, + optionMergeStrategies: {}, + errorHandler: undefined, + warnHandler: undefined, + compilerOptions: {} + }, + mixins: [], + components: {}, + directives: {}, + provides: Object.create(null), + } +} + +const createApp = (rootComponent, rootProps = null) => { + //TODO + let isMounted = false; + const context = createAppContext(); + if (typeof rootComponent !== 'function') { + rootComponent = { ...rootComponent }; + } + const app = { + _component: rootComponent as ConcreteComponent, + _container: null, + mount: (rootContainer: Element) => { + if (!isMounted) { + const vnode = createVNode(rootComponent, rootProps); + render.render(vnode, rootContainer, false); + isMounted = true; + app._container = rootContainer as any; + (rootContainer as any).__vue_app__ = app; + return vnode.component!.proxy; + } else { + console.warn('App has already been mounted'); + } + } + }; + return app; +} + +export { + createApp +} From f17313702e93c4e39e65aa4db428ca9c8589ff51 Mon Sep 17 00:00:00 2001 From: icebox1234 <464752812@qq.com> Date: Sat, 29 Oct 2022 15:21:21 +0800 Subject: [PATCH 2/4] feat:homework --- package-lock.json | 20 ++++++++++++++++++++ package.json | 3 ++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 1979baf..b05398c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@vitejs/plugin-vue": "^3.0.3", "@vue/test-utils": "^2.0.2", "jsdom": "^20.0.0", + "typescript": "^4.8.4", "vite": "^3.0.9", "vitest": "^0.23.0" } @@ -1386,6 +1387,19 @@ "node": ">=4" } }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz", @@ -2570,6 +2584,12 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true + }, "universalify": { "version": "0.2.0", "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.2.0.tgz", diff --git a/package.json b/package.json index b984a5d..a421707 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "build": "vite build", "preview": "vite preview --port 4173", "test": "vitest --environment jsdom", - "tsc":"tsc src/mini-renderer.ts --target esnext" + "tsc": "tsc src/mini-renderer.ts --target esnext" }, "dependencies": { "vue": "^3.2.38" @@ -16,6 +16,7 @@ "@vitejs/plugin-vue": "^3.0.3", "@vue/test-utils": "^2.0.2", "jsdom": "^20.0.0", + "typescript": "^4.8.4", "vite": "^3.0.9", "vitest": "^0.23.0" } From f5912d6cd9ff1717c0993cb77111ce72a100c9ce Mon Sep 17 00:00:00 2001 From: icebox1234 <464752812@qq.com> Date: Sat, 29 Oct 2022 15:24:20 +0800 Subject: [PATCH 3/4] feat: homework --- .github/workflows/node.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 66f9635..000e15f 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -26,6 +26,6 @@ jobs: with: node-version: ${{ matrix.node-version }} - run: npm i - - run: npm tsc + - run: npm run tsc # Just run tests once - run: npm test \ No newline at end of file From 5a4aa49f67597d056e49c7d6cecafaf0a69cbddf Mon Sep 17 00:00:00 2001 From: icebox1234 <464752812@qq.com> Date: Sat, 29 Oct 2022 15:29:05 +0800 Subject: [PATCH 4/4] feat: homework --- package.json | 2 +- src/mini-renderer.ts | 2 +- tsconfig.json | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tsconfig.json diff --git a/package.json b/package.json index a421707..69f4abc 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "build": "vite build", "preview": "vite preview --port 4173", "test": "vitest --environment jsdom", - "tsc": "tsc src/mini-renderer.ts --target esnext" + "tsc": "tsc" }, "dependencies": { "vue": "^3.2.38" diff --git a/src/mini-renderer.ts b/src/mini-renderer.ts index f535905..1f3fa15 100644 --- a/src/mini-renderer.ts +++ b/src/mini-renderer.ts @@ -4,7 +4,7 @@ import { ConcreteComponent, createVNode, AppContext, -} from '@vue/runtime-core' +} from '@vue/runtime-core'; const render = createRenderer({ diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..35be4c4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "target": "ESNext", + "moduleResolution":"Node" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + }, + "files": [ + "src/mini-renderer.ts" + ] +}