diff --git a/packages/plugin-dva/src/getModels/fixtures/jsx/b.jsx b/packages/plugin-dva/src/getModels/fixtures/jsx/b.jsx new file mode 100644 index 000000000..a8891edad --- /dev/null +++ b/packages/plugin-dva/src/getModels/fixtures/jsx/b.jsx @@ -0,0 +1,8 @@ +import React from 'react'; + +const A = () =>
123
+const AbcModel = { + namespace: 'a', +}; + +export default AbcModel; diff --git a/packages/plugin-dva/src/getModels/getModels.test.ts b/packages/plugin-dva/src/getModels/getModels.test.ts index 3e24a5ca2..d22d17e07 100644 --- a/packages/plugin-dva/src/getModels/getModels.test.ts +++ b/packages/plugin-dva/src/getModels/getModels.test.ts @@ -62,9 +62,25 @@ test('getModels with opts.extraModels and opts.skipModelValidate', () => { ]); }); -test('parser error when has jsx', () => { +// test('parser error when has jsx', () => { +// const base = join(fixtures, 'jsx'); +// const filePath = join(base, 'a.jsx'); +// expect(() => { +// getModels({ +// base, +// cwd: __dirname, +// skipModelValidate: false, +// }); +// }).toThrow( +// `Dva model ${utils.winPath( +// relative(__dirname, filePath), +// )} parse failed, SyntaxError: Unterminated regular expression. (3:26)`, +// ); +// }); + +test('parser error when ambiguous with jsx', () => { const base = join(fixtures, 'jsx'); - const filePath = join(base, 'a.jsx'); + const filePath = join(base, 'b.jsx'); expect(() => { getModels({ base, @@ -74,6 +90,6 @@ test('parser error when has jsx', () => { }).toThrow( `Dva model ${utils.winPath( relative(__dirname, filePath), - )} parse failed, SyntaxError: Unterminated regular expression. (3:26)`, + )} parse failed, SyntaxError: Unterminated JSX contents. (5:21) Maybe you use type assertions that would be ambiguous with JSX`, ); }); diff --git a/packages/plugin-dva/src/getModels/getModels.ts b/packages/plugin-dva/src/getModels/getModels.ts index d00e8c04b..be094b6e0 100644 --- a/packages/plugin-dva/src/getModels/getModels.ts +++ b/packages/plugin-dva/src/getModels/getModels.ts @@ -27,16 +27,23 @@ export function getModels(opts: { // 允许通过配置下跳过 Model 校验 if (opts.skipModelValidate) return true; + const isJsx = /.(j|t)sx$/.test(f); // TODO: fs cache for performance try { - return isValidModel({ - content: readFileSync(f, 'utf-8'), - }); + return isValidModel( + { + content: readFileSync(f, 'utf-8'), + }, + isJsx, + ); } catch (error) { throw new Error( `Dva model ${utils.winPath( relative(opts.cwd, f), - )} parse failed, ${error}`, + )} parse failed, ${error} ${ + isJsx && + 'Maybe you use type assertions that would be ambiguous with JSX' + }`, ); } }); diff --git a/packages/plugin-dva/src/getModels/isValidModel.test.ts b/packages/plugin-dva/src/getModels/isValidModel.test.ts index 8077bb55e..843579e7a 100644 --- a/packages/plugin-dva/src/getModels/isValidModel.test.ts +++ b/packages/plugin-dva/src/getModels/isValidModel.test.ts @@ -86,3 +86,23 @@ export default foo(model, { namespace: 'foo' }); }), ).toEqual(false); }); + +test('isValidModel with jsx', () => { + expect( + isValidModel( + { + content: ` +const t = () =>
; +export default { + reducers: { + add(){ + t(); + } + } +} +`, + }, + true, + ), + ).toEqual(true); +}); diff --git a/packages/plugin-dva/src/getModels/isValidModel.ts b/packages/plugin-dva/src/getModels/isValidModel.ts index e044c42f0..2687b6f34 100644 --- a/packages/plugin-dva/src/getModels/isValidModel.ts +++ b/packages/plugin-dva/src/getModels/isValidModel.ts @@ -29,8 +29,7 @@ function getTSNode(node: any) { } } -export function isValidModel({ content }: { content: string }) { - const { parser } = utils; +export function isValidModel({ content }: { content: string }, isJsx = false) { const ast = parser.parse(content, { sourceType: 'module', plugins: [ @@ -44,7 +43,7 @@ export function isValidModel({ content }: { content: string }) { 'objectRestSpread', 'optionalChaining', 'decorators-legacy', - ], + ].concat(isJsx ? ['jsx'] : []), }); let isDvaModel = false;