Skip to content

Commit

Permalink
Refactor: mock service (alibaba#4015)
Browse files Browse the repository at this point in the history
* fix: set cors before all served files

* feat: support ts in mock file

* feat: babel-preset-ice

* fix: remove useless code

* fix: trace rules
  • Loading branch information
ClarkXia authored Jan 14, 2021
1 parent 1df6ddf commit 9c7a263
Show file tree
Hide file tree
Showing 16 changed files with 302 additions and 96 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
const projects = require('./projects');
import projects from './projects';

interface IStatus {
name: string;
}
const status = 'SUCCESS';
// mock/index.js
module.exports = {
export default {
'GET /api/repo': {
status: 'SUCCESS',
status,
data: {
group: 'ice.js',
url: 'http://github.com/ice-lab/ice.js'
}
},

'GET /api/projects': {
status: 'SUCCESS',
data: projects
status,
data: projects
}
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = [
export default [
{
id: 1,
name: 'facebook/react',
Expand Down
1 change: 1 addition & 0 deletions packages/babel-preset-ice/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# babel-preset-ice
38 changes: 38 additions & 0 deletions packages/babel-preset-ice/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "babel-preset-ice",
"version": "1.0.0",
"description": "Basic babel preset",
"main": "lib/index.js",
"types": "types/index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"plugin",
"babel"
],
"author": "",
"license": "MIT",
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.2",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.1.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.1.0",
"@babel/preset-env": "^7.4.0",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3"
}
}
53 changes: 53 additions & 0 deletions packages/babel-preset-ice/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
interface IOpts {
typescript?: boolean;
env?: object;
react?: boolean;
}
/**
* babel config
*/
function resolvePlugin(plugins) {
return plugins.filter(Boolean).map((plugin) => {
if (Array.isArray(plugin)) {
const [pluginName, ...args] = plugin;
return [require.resolve(pluginName), ...args];
}
return require.resolve(plugin);
});
}

export default (opts: IOpts = {}) => {
const plugins = [
// Stage 0
'@babel/plugin-proposal-function-bind',
// Stage 1
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-logical-assignment-operators',
['@babel/plugin-proposal-optional-chaining', { loose: false }],
['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }],
['@babel/plugin-proposal-nullish-coalescing-operator', { loose: false }],
'@babel/plugin-proposal-do-expressions',
// Stage 2
['@babel/plugin-proposal-decorators', { legacy: true }],
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
// Stage 3
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
['@babel/plugin-proposal-class-properties', { loose: true }],
'@babel/plugin-proposal-json-strings',
];

return {
presets: resolvePlugin([
opts.env && [
'@babel/preset-env', opts.env,
],
opts.typescript && '@babel/preset-typescript',
opts.react && '@babel/preset-react',
]),
plugins: resolvePlugin(plugins),
};
};
8 changes: 8 additions & 0 deletions packages/babel-preset-ice/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.settings.json",
"compilerOptions": {
"baseUrl": "./",
"rootDir": "src",
"outDir": "lib"
}
}
24 changes: 2 additions & 22 deletions packages/build-scripts-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "build-scripts-config",
"version": "0.1.9",
"version": "0.1.10",
"description": "Basic configs for build-scripts and its plugins",
"main": "lib/index.js",
"types": "types/index.d.ts",
Expand All @@ -17,27 +17,7 @@
"webpack": "^4.41.1"
},
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.2",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.1.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.1.0",
"@babel/preset-env": "^7.4.0",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.3.3",
"babel-preset-ice": "^1.0.0",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
"camelcase": "^5.3.1",
Expand Down
59 changes: 10 additions & 49 deletions packages/build-scripts-config/src/config/babel/index.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,13 @@
/**
* babel config
*/
function resolvePlugin(plugins) {
return plugins.filter(Boolean).map((plugin) => {
if (Array.isArray(plugin)) {
const [pluginName, ...args] = plugin;
return [require.resolve(pluginName), ...args];
}
return require.resolve(plugin);
});
}
const getBabelPreset = require('babel-preset-ice').default;

module.exports = () => {
const plugins = [
// Stage 0
'@babel/plugin-proposal-function-bind',
// Stage 1
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-logical-assignment-operators',
['@babel/plugin-proposal-optional-chaining', { loose: false }],
['@babel/plugin-proposal-pipeline-operator', { proposal: 'minimal' }],
['@babel/plugin-proposal-nullish-coalescing-operator', { loose: false }],
'@babel/plugin-proposal-do-expressions',
// Stage 2
['@babel/plugin-proposal-decorators', { legacy: true }],
'@babel/plugin-proposal-function-sent',
'@babel/plugin-proposal-export-namespace-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
// Stage 3
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-syntax-import-meta',
['@babel/plugin-proposal-class-properties', { loose: true }],
'@babel/plugin-proposal-json-strings',
];

return {
presets: resolvePlugin([
[
'@babel/preset-env', {
modules: false,
useBuiltIns: 'entry',
corejs: 3,
},
],
'@babel/preset-typescript',
'@babel/preset-react',
]),
plugins: resolvePlugin(plugins),
};
return getBabelPreset({
react: true,
typescript: true,
env: {
modules: false,
useBuiltIns: 'entry',
corejs: 3,
}
});
};
6 changes: 6 additions & 0 deletions packages/build-user-config/src/userConfig/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ module.exports = (config, mock, context) => {
// replace devServer before function
config.merge({ devServer: {
before(app, server) {
// set cors before all served files
app.use((req, res, next) => {
res.set('Access-Control-Allow-Origin', '*');
next();
});
// keep mock server ahead of devServer.before
webpackDevMock(app);
if (typeof originalDevServeBefore === 'function') {
originalDevServeBefore(app, server);
Expand Down
5 changes: 5 additions & 0 deletions packages/webpack-dev-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
"author": "[email protected]",
"license": "MIT",
"dependencies": {
"babel-preset-ice": "^1.0.0",
"@babel/parser": "^7.12.11",
"@babel/traverse": "^7.12.12",
"@babel/register": "^7.12.10",
"body-parser": "^1.18.3",
"chalk": "^2.4.1",
"chokidar": "^2.0.4",
"debug": "^3.1.0",
"express-http-proxy": "^1.2.0",
"fs-extra": "^9.0.1",
"glob": "^7.1.4",
"multer": "^1.4.2",
"path-to-regexp": "^6.0.0"
Expand Down
83 changes: 83 additions & 0 deletions packages/webpack-dev-mock/src/analyzeMockDeps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { parse } from '@babel/parser';
import traverse from '@babel/traverse';
import * as fse from 'fs-extra';
import * as path from 'path';

function parseCode(code) {
return parse(code, {
sourceType: 'module',
plugins: ['jsx', 'typescript', 'decorators-legacy', 'dynamicImport', 'classProperties'],
});
}

function analyzeAST(code: string, dir: string) {
const result = [];
const ast = parseCode(code);
const visitor = {
// const xx = require('./xx');
CallExpression(nodePath) {
const { callee, arguments: args } = nodePath.node;
if (
callee.type === 'Identifier' &&
callee.name === 'require' &&
args.length === 1 &&
args[0].type === 'StringLiteral'
) {
result.push(args[0].value);
}
},
// import xx from 'xx';
ImportDeclaration(nodePath) {
result.push(nodePath.node.source.value);
},
// export * from 'xx';
ExportAllDeclaration(nodePath) {
const { node } = nodePath;
if (node.source) {
result.push(node.source.value);
}
},
// export * as xx from 'xx';
ExportNamedDeclaration(nodePath) {
const { node } = nodePath;
if (node.source) {
result.push(node.source.value);
}
},
};
traverse(ast, visitor);
// only analyze relative path
return result.filter((module) => /^\./.test(module)).map((modulePath) => path.join(dir, modulePath));
}

function dedupe(arr: string[]) {
if (!Array.isArray(arr)) {
throw new TypeError('[dedupe]: arr should be an array;');
}
const map = {};
for (let i = 0, len = arr.length; i < len; i++) {
const key = arr[i];
map[key] = true;
}
return Object.keys(map);
}

function analyzeDenpendencies(filePath: string) {
const tracedFiles = {};
const result = [];
function trace(file: string) {
if (!tracedFiles[file]) {
tracedFiles[file] = true;
const fileContent = String(fse.readFileSync(file));
const analyzeResult = dedupe(analyzeAST(fileContent, path.dirname(file)));
result.push(...analyzeResult);
analyzeResult.forEach(modulePath => {
trace(require.resolve(modulePath));
});
}
}
trace(require.resolve(filePath));
return dedupe(result);
}

export default analyzeDenpendencies;
13 changes: 13 additions & 0 deletions packages/webpack-dev-mock/src/babelPresetNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import getBabelPreset from 'babel-preset-ice';

export default () => {
return getBabelPreset({
env: {
targets: {
node: 'current',
},
modules: 'commonjs',
},
typescript: true
});
};
Loading

0 comments on commit 9c7a263

Please sign in to comment.