From c0dbc22ac1d9895a0cb6eaeb2ca43f1fd5975d19 Mon Sep 17 00:00:00 2001 From: yuche Date: Thu, 24 Oct 2019 17:57:02 +0800 Subject: [PATCH] =?UTF-8?q?test(loader):=20=E6=B7=BB=E5=8A=A0=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/taro-loader/__tests__/app.test.js | 33 +++++++++++++ packages/taro-loader/__tests__/compile.js | 15 ++++-- .../__tests__/fixtures/not-export-default.txt | 1 + .../__tests__/fixtures/react-imported-2.txt | 4 ++ .../__tests__/fixtures/react-imported.txt | 3 ++ .../taro-loader/__tests__/fixtures/react.txt | 9 ++++ .../taro-loader/__tests__/fixtures/react2.txt | 9 ++++ .../__tests__/fixtures/syntax-tsx.txt | 9 ++++ .../__tests__/fixtures/vue-imported.txt | 3 ++ .../taro-loader/__tests__/general.spec.js | 33 +++++++++++++ packages/taro-loader/__tests__/page.test.js | 46 +++++++++++++++++++ packages/taro-loader/src/app.ts | 13 ++++-- packages/taro-loader/src/index.ts | 13 ++++++ packages/taro-loader/src/loader.ts | 2 +- packages/taro-loader/src/page.ts | 2 +- 15 files changed, 186 insertions(+), 9 deletions(-) create mode 100644 packages/taro-loader/__tests__/fixtures/not-export-default.txt create mode 100644 packages/taro-loader/__tests__/fixtures/react-imported-2.txt create mode 100644 packages/taro-loader/__tests__/fixtures/react-imported.txt create mode 100644 packages/taro-loader/__tests__/fixtures/react.txt create mode 100644 packages/taro-loader/__tests__/fixtures/react2.txt create mode 100644 packages/taro-loader/__tests__/fixtures/syntax-tsx.txt create mode 100644 packages/taro-loader/__tests__/fixtures/vue-imported.txt create mode 100644 packages/taro-loader/__tests__/general.spec.js create mode 100644 packages/taro-loader/src/index.ts diff --git a/packages/taro-loader/__tests__/app.test.js b/packages/taro-loader/__tests__/app.test.js index fa63afe74f3c..4554a5ee2110 100644 --- a/packages/taro-loader/__tests__/app.test.js +++ b/packages/taro-loader/__tests__/app.test.js @@ -13,6 +13,29 @@ describe('app loader', () => { App(createReactApp(React, app, ReactDOM.render)); `)) }) + + test('没有 export default 应该报错', async () => { + const result = await compile('basic_1.txt', { type: 'app', framework: 'react' }) + // expect(true).toBe(false) + expect(result).toBe(pretty(` + import ReactDOM from "react-dom"; + import React from "react"; + import { createReactApp } from "@tarojs/runtime"; + import { app } from "./app"; + App(createReactApp(React, app, ReactDOM.render)); + `)) + }) + + test('不重复添加依赖', async () => { + const result = await compile('react-imported.txt', { type: 'app', framework: 'react' }) + expect(result).toBe(pretty(` + import ReactDOM from "react-dom"; + import { createReactApp } from "@tarojs/runtime"; + import React from "react"; + import { app } from "./app"; + App(createReactApp(React, app, ReactDOM.render)); + `)) + }) }) describe('vue', () => { @@ -26,5 +49,15 @@ describe('app loader', () => { App(createVueApp(Vue, app)); `)) }) + + test('不重复添加依赖', async () => { + const result = await compile('vue-imported.txt', { type: 'app', framework: 'vue' }) + expect(result).toBe(pretty(` + import { createVueApp } from "@tarojs/runtime"; + import Vue from "vue"; + import { app } from "./app"; + App(createVueApp(Vue, app)); + `)) + }) }) }) diff --git a/packages/taro-loader/__tests__/compile.js b/packages/taro-loader/__tests__/compile.js index 941ea1b0c652..0423d74df809 100644 --- a/packages/taro-loader/__tests__/compile.js +++ b/packages/taro-loader/__tests__/compile.js @@ -32,11 +32,18 @@ export async function compile (fixture, { type, framework }) { module: { rules: [{ test: /\.txt$/, - use: { - loader: path.resolve(__dirname, `../lib/${type}.js`), - options: { - framework + use: [ + { + loader: path.resolve(__dirname, `../lib/${type}.js`), + options: { + framework + } } + ] + }, { + test: /\.js$/, + use: { + loader: 'babel-loader' } }] } diff --git a/packages/taro-loader/__tests__/fixtures/not-export-default.txt b/packages/taro-loader/__tests__/fixtures/not-export-default.txt new file mode 100644 index 000000000000..2685ae73be52 --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/not-export-default.txt @@ -0,0 +1 @@ +const a = 'b' diff --git a/packages/taro-loader/__tests__/fixtures/react-imported-2.txt b/packages/taro-loader/__tests__/fixtures/react-imported-2.txt new file mode 100644 index 000000000000..361f3f11f4bf --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/react-imported-2.txt @@ -0,0 +1,4 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import { app } from './app' +export default app diff --git a/packages/taro-loader/__tests__/fixtures/react-imported.txt b/packages/taro-loader/__tests__/fixtures/react-imported.txt new file mode 100644 index 000000000000..c808527808dd --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/react-imported.txt @@ -0,0 +1,3 @@ +import React from 'react' +import { app } from './app' +export default app diff --git a/packages/taro-loader/__tests__/fixtures/react.txt b/packages/taro-loader/__tests__/fixtures/react.txt new file mode 100644 index 000000000000..e421023326b4 --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/react.txt @@ -0,0 +1,9 @@ +import React from 'react' + +class A extends Component { + render () { + return React.createElement('div') + } +} + +export default connect({})(A) diff --git a/packages/taro-loader/__tests__/fixtures/react2.txt b/packages/taro-loader/__tests__/fixtures/react2.txt new file mode 100644 index 000000000000..5d121c9446d5 --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/react2.txt @@ -0,0 +1,9 @@ +import React from 'react' + +class A extends Component { + render () { + return React.createElement('div') + } +} + +export default A \ No newline at end of file diff --git a/packages/taro-loader/__tests__/fixtures/syntax-tsx.txt b/packages/taro-loader/__tests__/fixtures/syntax-tsx.txt new file mode 100644 index 000000000000..43122177de13 --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/syntax-tsx.txt @@ -0,0 +1,9 @@ +const a: string = '' + +class A extends Component { + render () { + return
+ } +} + +export default A diff --git a/packages/taro-loader/__tests__/fixtures/vue-imported.txt b/packages/taro-loader/__tests__/fixtures/vue-imported.txt new file mode 100644 index 000000000000..5d19471c9812 --- /dev/null +++ b/packages/taro-loader/__tests__/fixtures/vue-imported.txt @@ -0,0 +1,3 @@ +import Vue from 'vue' +import { app } from './app' +export default app diff --git a/packages/taro-loader/__tests__/general.spec.js b/packages/taro-loader/__tests__/general.spec.js new file mode 100644 index 000000000000..a79769d54f17 --- /dev/null +++ b/packages/taro-loader/__tests__/general.spec.js @@ -0,0 +1,33 @@ +import { compile } from './compile' + +describe('general', () => { + describe('not export default', () => { + test('app', async () => { + async function check () { + await compile('not-export-default.txt', { type: 'app', framework: 'vue' }) + } + await expect(check()).rejects.toBeTruthy() + }) + + test('page', async () => { + async function check () { + await compile('not-export-default.txt', { type: 'page', framework: 'vue' }) + } + await expect(check()).rejects.toBeTruthy() + }) + + test('react', async () => { + async function check () { + await compile('not-export-default.txt', { type: 'app', framework: 'react' }) + } + await expect(check()).rejects.toBeTruthy() + }) + }) + + describe.skip('syntax', () => { + test('tsx', async () => { + const result = await compile('syntax-tsx.txt', { type: 'page', framework: 'react' }) + expect(result).toBe('') + }) + }) +}) diff --git a/packages/taro-loader/__tests__/page.test.js b/packages/taro-loader/__tests__/page.test.js index c37168fae80e..3d68aa199867 100644 --- a/packages/taro-loader/__tests__/page.test.js +++ b/packages/taro-loader/__tests__/page.test.js @@ -11,5 +11,51 @@ describe('page loader', () => { Page(createPageConfig(app)); `)) }) + + test('react component', async () => { + const result = await compile('react.txt', { type: 'page', framework: 'react' }) + + expect(result).toBe(pretty(` + import { createPageConfig } from "@tarojs/runtime"; + import React from "react"; + + class A extends Component { + render() { + return React.createElement("div"); + } + } + + Page(createPageConfig(connect({})(A))); + `)) + }) + + test('react component 2', async () => { + const result = await compile('react2.txt', { type: 'page', framework: 'react' }) + + expect(result).toBe(pretty(` + import { createPageConfig } from "@tarojs/runtime"; + import React from "react"; + + class A extends Component { + render() { + return React.createElement("div"); + } + } + + Page(createPageConfig(connect({})(A))); + `)) + }) + }) + + describe('vue', () => { + test('basic', async () => { + const result = await compile('basic_1.txt', { type: 'page', framework: 'vue' }) + + expect(result).toBe(pretty(` + import { createPageConfig } from "@tarojs/runtime"; + import { app } from "./app"; + Page(createPageConfig(app)); + `)) + }) }) }) diff --git a/packages/taro-loader/src/app.ts b/packages/taro-loader/src/app.ts index 61f40cdcb5e3..1397cb6507d5 100644 --- a/packages/taro-loader/src/app.ts +++ b/packages/taro-loader/src/app.ts @@ -21,8 +21,13 @@ class AppLoader extends Loader { this.needToImportMainModule = true + let reactDOMImported = false + traverse(this.ast, { Program: { + enter: (path) => { + reactDOMImported = !!path.scope.getBinding('ReactDOM') + }, exit: this.ensureMainModuleImported.bind(this) } }) @@ -31,9 +36,11 @@ class AppLoader extends Loader { if (isReact) { if (this.framework === 'react') { - this.insertToTheFront( - t.importDeclaration([t.importDefaultSpecifier(t.identifier('ReactDOM'))], t.stringLiteral('react-dom')) - ) + if (!reactDOMImported) { + this.insertToTheFront( + t.importDeclaration([t.importDefaultSpecifier(t.identifier('ReactDOM'))], t.stringLiteral('react-dom')) + ) + } render = t.memberExpression(t.identifier('ReactDOM'), t.identifier('render')) } else { diff --git a/packages/taro-loader/src/index.ts b/packages/taro-loader/src/index.ts new file mode 100644 index 000000000000..34dd68e43619 --- /dev/null +++ b/packages/taro-loader/src/index.ts @@ -0,0 +1,13 @@ +import { getOptions } from 'loader-utils' +import * as webpack from 'webpack' +import appLoader from './app' +import pageLoader from './page' + +export default function (this: webpack.loader.LoaderContext, source: string) { + const options = getOptions(this) + if (options.type === 'app') { + appLoader.call(this, source) + } else { + pageLoader.call(this, source) + } +} diff --git a/packages/taro-loader/src/loader.ts b/packages/taro-loader/src/loader.ts index 110ad96761a2..195de09e1ce0 100644 --- a/packages/taro-loader/src/loader.ts +++ b/packages/taro-loader/src/loader.ts @@ -85,7 +85,7 @@ export class Loader { } if (this.exportDefaultDecl == null) { - this.context.emitError(`文件: ${this.context.resourcePath} 没有找到 export default 语句!`) + this.context.emitError(new Error(`文件: ${this.context.resourcePath} 没有找到 export default 语句!`)) } return file diff --git a/packages/taro-loader/src/page.ts b/packages/taro-loader/src/page.ts index 6d3c0334570d..6b1f229e4575 100644 --- a/packages/taro-loader/src/page.ts +++ b/packages/taro-loader/src/page.ts @@ -71,7 +71,7 @@ class PageLoader extends Loader { } private injectReactComponent (classDecl: NodePath) { - if (this.framework !== 'vue') { + if (this.framework === 'vue') { return }