Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/plugin-dva/src/getModels/fixtures/jsx/b.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from 'react';

const A = () => <div>123</div>
const AbcModel = {
namespace: <string>'a',
};

export default AbcModel;
22 changes: 19 additions & 3 deletions packages/plugin-dva/src/getModels/getModels.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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`,
);
});
15 changes: 11 additions & 4 deletions packages/plugin-dva/src/getModels/getModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}`,
);
}
});
Expand Down
20 changes: 20 additions & 0 deletions packages/plugin-dva/src/getModels/isValidModel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,23 @@ export default foo(model, { namespace: 'foo' });
}),
).toEqual(false);
});

test('isValidModel with jsx', () => {
expect(
isValidModel(
{
content: `
const t = () => <div/>;
export default {
reducers: {
add(){
t();
}
}
}
`,
},
true,
),
).toEqual(true);
});
5 changes: 2 additions & 3 deletions packages/plugin-dva/src/getModels/isValidModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand All @@ -44,7 +43,7 @@ export function isValidModel({ content }: { content: string }) {
'objectRestSpread',
'optionalChaining',
'decorators-legacy',
],
].concat(isJsx ? ['jsx'] : []),
});

let isDvaModel = false;
Expand Down