@modern-js/plugin-polyfill 1.2.0 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +7 -0
- package/CHANGELOG.md +32 -0
- package/dist/js/modern/cli.js +18 -19
- package/dist/js/modern/index.js +47 -47
- package/dist/js/node/cli.js +18 -20
- package/dist/js/node/index.js +48 -49
- package/dist/types/cli.d.ts +3 -16
- package/dist/types/index.d.ts +3 -1
- package/package.json +5 -9
- package/tests/.eslintrc.js +6 -0
- package/tests/index.test.ts +53 -0
- package/tests/tsconfig.json +9 -0
- package/tsconfig.json +1 -1
- package/src/cli.ts +0 -20
- package/src/const.ts +0 -5
- package/src/global.d.ts +0 -7
- package/src/index.ts +0 -66
- package/src/libs/cache.ts +0 -49
- package/src/type.ts +0 -7
package/.eslintrc.js
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @modern-js/plugin-polyfill
|
|
2
2
|
|
|
3
|
+
## 1.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c7dc7f54: migrate to new plugin style
|
|
8
|
+
- 2008fdbd: convert two packages server part, support server load plugin itself
|
|
9
|
+
|
|
10
|
+
## 1.2.2
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 272cab15: refactor server plugin manager
|
|
15
|
+
- Updated dependencies [d9cc5ea9]
|
|
16
|
+
- Updated dependencies [bd819a8d]
|
|
17
|
+
- Updated dependencies [d099e5c5]
|
|
18
|
+
- Updated dependencies [bada2879]
|
|
19
|
+
- Updated dependencies [24f616ca]
|
|
20
|
+
- Updated dependencies [272cab15]
|
|
21
|
+
- @modern-js/core@1.4.0
|
|
22
|
+
- @modern-js/server-core@1.2.2
|
|
23
|
+
|
|
24
|
+
## 1.2.1
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 83166714: change .npmignore
|
|
29
|
+
- Updated dependencies [83166714]
|
|
30
|
+
- Updated dependencies [c3de9882]
|
|
31
|
+
- Updated dependencies [33ff48af]
|
|
32
|
+
- @modern-js/core@1.3.2
|
|
33
|
+
- @modern-js/server-plugin@1.2.1
|
|
34
|
+
|
|
3
35
|
## 1.2.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/dist/js/modern/cli.js
CHANGED
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import { createPlugin, useResolvedConfigContext } from '@modern-js/core';
|
|
2
1
|
import { defaultPolyfill } from "./const";
|
|
3
|
-
export default
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
export default (() => ({
|
|
3
|
+
name: '@modern-js/plugin-polyfill',
|
|
4
|
+
setup: api => ({
|
|
5
|
+
htmlPartials({
|
|
6
|
+
entrypoint,
|
|
7
|
+
partials
|
|
8
|
+
}) {
|
|
9
|
+
const resolvedConfig = api.useResolvedConfigContext();
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
if (resolvedConfig.output.polyfill === 'ua') {
|
|
12
|
+
partials.top.push(`<script src="${defaultPolyfill}" crossorigin></script>`);
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
return {
|
|
16
|
+
partials,
|
|
17
|
+
entrypoint
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
20
|
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
});
|
|
21
|
+
})
|
|
22
|
+
}));
|
package/dist/js/modern/index.js
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
import { createPlugin } from '@modern-js/server-plugin';
|
|
2
1
|
import { getPolyfillString } from '@modern-js/polyfill-lib';
|
|
3
2
|
import mime from 'mime-types';
|
|
4
3
|
import Parser from 'ua-parser-js';
|
|
5
4
|
import { defaultFeatures, defaultPolyfill } from "./const";
|
|
6
5
|
import PolyfillCache, { generateCacheKey } from "./libs/cache";
|
|
7
|
-
export default
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
export default (() => ({
|
|
7
|
+
name: '@modern-js/plugin-polyfill',
|
|
8
|
+
setup: () => ({
|
|
9
|
+
preServerInit(_) {
|
|
10
|
+
const cache = new PolyfillCache();
|
|
11
|
+
const route = defaultPolyfill;
|
|
12
|
+
const features = defaultFeatures;
|
|
13
|
+
const minify = process.env.NODE_ENV === 'production';
|
|
14
|
+
const featureDig = Object.keys(features).map(name => {
|
|
15
|
+
const {
|
|
16
|
+
flags = ['gated']
|
|
17
|
+
} = features[name];
|
|
18
|
+
const flagStr = flags.join(',');
|
|
19
|
+
return `${name}-${flagStr}`;
|
|
20
|
+
}).join(',');
|
|
21
|
+
return async (context, next) => {
|
|
22
|
+
if (context.url !== route) {
|
|
23
|
+
return next();
|
|
24
|
+
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
const parsedUA = Parser(context.headers['user-agent']);
|
|
27
|
+
const {
|
|
28
|
+
name = '',
|
|
29
|
+
version = ''
|
|
30
|
+
} = parsedUA.browser;
|
|
31
|
+
const cacheKey = generateCacheKey({
|
|
32
|
+
name,
|
|
33
|
+
version,
|
|
34
|
+
features: featureDig,
|
|
35
|
+
minify
|
|
36
|
+
});
|
|
37
|
+
const matched = cache.get(cacheKey);
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
if (matched) {
|
|
40
|
+
context.res.setHeader('content-type', mime.contentType('js'));
|
|
41
|
+
return context.res.end(matched);
|
|
42
|
+
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
const polyfill = await getPolyfillString({
|
|
45
|
+
uaString: context.headers['user-agent'],
|
|
46
|
+
minify,
|
|
47
|
+
features
|
|
48
|
+
});
|
|
49
|
+
cache.set(cacheKey, polyfill);
|
|
50
|
+
context.res.setHeader('content-type', mime.contentType('js'));
|
|
51
|
+
return context.res.end(polyfill);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
53
54
|
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
});
|
|
55
|
+
})
|
|
56
|
+
}));
|
package/dist/js/node/cli.js
CHANGED
|
@@ -5,30 +5,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var _core = require("@modern-js/core");
|
|
9
|
-
|
|
10
8
|
var _const = require("./const");
|
|
11
9
|
|
|
12
|
-
var _default = (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
var _default = () => ({
|
|
11
|
+
name: '@modern-js/plugin-polyfill',
|
|
12
|
+
setup: api => ({
|
|
13
|
+
htmlPartials({
|
|
14
|
+
entrypoint,
|
|
15
|
+
partials
|
|
16
|
+
}) {
|
|
17
|
+
const resolvedConfig = api.useResolvedConfigContext();
|
|
18
|
+
|
|
19
|
+
if (resolvedConfig.output.polyfill === 'ua') {
|
|
20
|
+
partials.top.push(`<script src="${_const.defaultPolyfill}" crossorigin></script>`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
partials,
|
|
25
|
+
entrypoint
|
|
26
|
+
};
|
|
22
27
|
}
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
partials,
|
|
26
|
-
entrypoint
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
}), {
|
|
31
|
-
name: '@modern-js/plugin-polyfill'
|
|
29
|
+
})
|
|
32
30
|
});
|
|
33
31
|
|
|
34
32
|
exports.default = _default;
|
package/dist/js/node/index.js
CHANGED
|
@@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var _serverPlugin = require("@modern-js/server-plugin");
|
|
9
|
-
|
|
10
8
|
var _polyfillLib = require("@modern-js/polyfill-lib");
|
|
11
9
|
|
|
12
10
|
var _mimeTypes = _interopRequireDefault(require("mime-types"));
|
|
@@ -23,55 +21,56 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
23
21
|
|
|
24
22
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
23
|
|
|
26
|
-
var _default = (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
24
|
+
var _default = () => ({
|
|
25
|
+
name: '@modern-js/plugin-polyfill',
|
|
26
|
+
setup: () => ({
|
|
27
|
+
preServerInit(_) {
|
|
28
|
+
const cache = new _cache.default();
|
|
29
|
+
const route = _const.defaultPolyfill;
|
|
30
|
+
const features = _const.defaultFeatures;
|
|
31
|
+
const minify = process.env.NODE_ENV === 'production';
|
|
32
|
+
const featureDig = Object.keys(features).map(name => {
|
|
33
|
+
const {
|
|
34
|
+
flags = ['gated']
|
|
35
|
+
} = features[name];
|
|
36
|
+
const flagStr = flags.join(',');
|
|
37
|
+
return `${name}-${flagStr}`;
|
|
38
|
+
}).join(',');
|
|
39
|
+
return async (context, next) => {
|
|
40
|
+
if (context.url !== route) {
|
|
41
|
+
return next();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const parsedUA = (0, _uaParserJs.default)(context.headers['user-agent']);
|
|
45
|
+
const {
|
|
46
|
+
name = '',
|
|
47
|
+
version = ''
|
|
48
|
+
} = parsedUA.browser;
|
|
49
|
+
const cacheKey = (0, _cache.generateCacheKey)({
|
|
50
|
+
name,
|
|
51
|
+
version,
|
|
52
|
+
features: featureDig,
|
|
53
|
+
minify
|
|
54
|
+
});
|
|
55
|
+
const matched = cache.get(cacheKey);
|
|
56
|
+
|
|
57
|
+
if (matched) {
|
|
58
|
+
context.res.setHeader('content-type', _mimeTypes.default.contentType('js'));
|
|
59
|
+
return context.res.end(matched);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const polyfill = await (0, _polyfillLib.getPolyfillString)({
|
|
63
|
+
uaString: context.headers['user-agent'],
|
|
64
|
+
minify,
|
|
65
|
+
features
|
|
66
|
+
});
|
|
67
|
+
cache.set(cacheKey, polyfill);
|
|
58
68
|
context.res.setHeader('content-type', _mimeTypes.default.contentType('js'));
|
|
59
|
-
return context.res.end(
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const polyfill = await (0, _polyfillLib.getPolyfillString)({
|
|
63
|
-
uaString: context.headers['user-agent'],
|
|
64
|
-
minify,
|
|
65
|
-
features
|
|
66
|
-
});
|
|
67
|
-
cache.set(cacheKey, polyfill);
|
|
68
|
-
context.res.setHeader('content-type', _mimeTypes.default.contentType('js'));
|
|
69
|
-
return context.res.end(polyfill);
|
|
70
|
-
};
|
|
71
|
-
}
|
|
69
|
+
return context.res.end(polyfill);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
72
|
|
|
73
|
-
})
|
|
74
|
-
name: '@modern-js/plugin-polyfill'
|
|
73
|
+
})
|
|
75
74
|
});
|
|
76
75
|
|
|
77
76
|
exports.default = _default;
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
resolved: import("@modern-js/core").NormalizedConfig;
|
|
5
|
-
}>;
|
|
6
|
-
validateSchema: import("@modern-js/core").ParallelWorkflow<void, unknown>;
|
|
7
|
-
prepare: import("@modern-js/core").AsyncWorkflow<void, void>;
|
|
8
|
-
commands: import("@modern-js/core").AsyncWorkflow<{
|
|
9
|
-
program: import("commander").Command;
|
|
10
|
-
}, void>;
|
|
11
|
-
watchFiles: import("@modern-js/core").ParallelWorkflow<void, unknown>;
|
|
12
|
-
fileChange: import("@modern-js/core").AsyncWorkflow<{
|
|
13
|
-
filename: string;
|
|
14
|
-
}, void>;
|
|
15
|
-
beforeExit: import("@modern-js/core").AsyncWorkflow<void, void>;
|
|
16
|
-
} & import("@modern-js/core").ClearDraftProgress<import("@modern-js/core").Hooks>>>>;
|
|
1
|
+
import type { CliPlugin } from '@modern-js/core';
|
|
2
|
+
|
|
3
|
+
declare const _default: () => CliPlugin;
|
|
17
4
|
|
|
18
5
|
export default _default;
|
package/dist/types/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"modern",
|
|
12
12
|
"modern.js"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.2.
|
|
14
|
+
"version": "1.2.3",
|
|
15
15
|
"jsnext:source": "./src/index.ts",
|
|
16
16
|
"types": "./dist/types/index.d.ts",
|
|
17
17
|
"main": "./dist/js/node/index.js",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@babel/runtime": "^7",
|
|
40
40
|
"@modern-js/polyfill-lib": "^1.0.0",
|
|
41
|
-
"@modern-js/server-plugin": "^1.2.0",
|
|
42
41
|
"lru-cache": "^6.0.0",
|
|
43
42
|
"mime-types": "^2.1.32",
|
|
44
43
|
"ua-parser-js": "^0.7.28"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
|
-
"@modern-js/
|
|
46
|
+
"@modern-js/server-core": "^1.2.3",
|
|
47
|
+
"@modern-js/types": "^1.3.5",
|
|
48
48
|
"@types/jest": "^26",
|
|
49
49
|
"@types/lru-cache": "^5.1.1",
|
|
50
50
|
"@types/mime-types": "^2.1.1",
|
|
@@ -53,14 +53,11 @@
|
|
|
53
53
|
"@types/react-dom": "^17",
|
|
54
54
|
"@types/ua-parser-js": "^0.7.36",
|
|
55
55
|
"typescript": "^4",
|
|
56
|
-
"@modern-js/core": "^1.
|
|
56
|
+
"@modern-js/core": "^1.5.0",
|
|
57
57
|
"@scripts/build": "0.0.0",
|
|
58
58
|
"jest": "^27",
|
|
59
59
|
"@scripts/jest-config": "0.0.0"
|
|
60
60
|
},
|
|
61
|
-
"peerDependencies": {
|
|
62
|
-
"@modern-js/core": "^1.3.0"
|
|
63
|
-
},
|
|
64
61
|
"sideEffects": false,
|
|
65
62
|
"modernConfig": {
|
|
66
63
|
"output": {
|
|
@@ -69,8 +66,7 @@
|
|
|
69
66
|
},
|
|
70
67
|
"publishConfig": {
|
|
71
68
|
"registry": "https://registry.npmjs.org/",
|
|
72
|
-
"access": "public"
|
|
73
|
-
"types": "./dist/types/index.d.ts"
|
|
69
|
+
"access": "public"
|
|
74
70
|
},
|
|
75
71
|
"scripts": {
|
|
76
72
|
"new": "modern new",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { NormalizedConfig } from '@modern-js/core';
|
|
2
|
+
import cliPugin from '../src/cli';
|
|
3
|
+
import serverPlugin from '../src';
|
|
4
|
+
import { defaultPolyfill } from '../src/const';
|
|
5
|
+
|
|
6
|
+
describe('plugin-static-hosting', () => {
|
|
7
|
+
it('cli', () => {
|
|
8
|
+
expect(cliPugin).toBeDefined();
|
|
9
|
+
const instance = cliPugin();
|
|
10
|
+
expect(instance.name).toBe('@modern-js/plugin-polyfill');
|
|
11
|
+
|
|
12
|
+
const hooks: any = instance.setup?.({
|
|
13
|
+
useResolvedConfigContext: () => {
|
|
14
|
+
return {
|
|
15
|
+
output: {},
|
|
16
|
+
} as NormalizedConfig;
|
|
17
|
+
},
|
|
18
|
+
} as any);
|
|
19
|
+
|
|
20
|
+
const params = { entrypoint: [], partials: [] };
|
|
21
|
+
expect(hooks.htmlPartials(params)).toEqual(params);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('server', async () => {
|
|
25
|
+
expect(serverPlugin).toBeDefined();
|
|
26
|
+
const instance = serverPlugin();
|
|
27
|
+
expect(instance.name).toBe('@modern-js/plugin-polyfill');
|
|
28
|
+
|
|
29
|
+
const hooks: any = instance.setup?.({} as any);
|
|
30
|
+
const fn = hooks.preServerInit();
|
|
31
|
+
expect(typeof fn).toBe('function');
|
|
32
|
+
|
|
33
|
+
const errorContext = { url: '' };
|
|
34
|
+
expect(await fn(errorContext, () => false)).toBeFalsy();
|
|
35
|
+
|
|
36
|
+
const context = {
|
|
37
|
+
url: defaultPolyfill,
|
|
38
|
+
res: {
|
|
39
|
+
setHeader: () => false,
|
|
40
|
+
end: (result: string) => result,
|
|
41
|
+
},
|
|
42
|
+
headers: {
|
|
43
|
+
'user-agent':
|
|
44
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const res = await fn(context);
|
|
49
|
+
expect(res).toMatch('modern polyfill');
|
|
50
|
+
const res1 = await fn(context);
|
|
51
|
+
expect(res1).toMatch('modern polyfill');
|
|
52
|
+
});
|
|
53
|
+
});
|
package/tsconfig.json
CHANGED
package/src/cli.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createPlugin, useResolvedConfigContext } from '@modern-js/core';
|
|
2
|
-
import { defaultPolyfill } from './const';
|
|
3
|
-
|
|
4
|
-
export default createPlugin(
|
|
5
|
-
() =>
|
|
6
|
-
({
|
|
7
|
-
htmlPartials({ entrypoint, partials }: any) {
|
|
8
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
9
|
-
const resolvedConfig = useResolvedConfigContext();
|
|
10
|
-
if (resolvedConfig.output.polyfill === 'ua') {
|
|
11
|
-
partials.top.push(
|
|
12
|
-
`<script src="${defaultPolyfill}" crossorigin></script>`,
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return { partials, entrypoint };
|
|
17
|
-
},
|
|
18
|
-
} as any),
|
|
19
|
-
{ name: '@modern-js/plugin-polyfill' },
|
|
20
|
-
);
|
package/src/const.ts
DELETED
package/src/global.d.ts
DELETED
package/src/index.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { createPlugin } from '@modern-js/server-plugin';
|
|
2
|
-
import { NextFunction, ModernServerContext } from '@modern-js/types/server';
|
|
3
|
-
import type { NormalizedConfig } from '@modern-js/core';
|
|
4
|
-
import { getPolyfillString } from '@modern-js/polyfill-lib';
|
|
5
|
-
import mime from 'mime-types';
|
|
6
|
-
import Parser from 'ua-parser-js';
|
|
7
|
-
import { defaultFeatures, defaultPolyfill } from './const';
|
|
8
|
-
import PolyfillCache, { generateCacheKey } from './libs/cache';
|
|
9
|
-
|
|
10
|
-
export default createPlugin(
|
|
11
|
-
() => ({
|
|
12
|
-
preServerInit(_: NormalizedConfig) {
|
|
13
|
-
const cache = new PolyfillCache();
|
|
14
|
-
const route = defaultPolyfill;
|
|
15
|
-
const features = defaultFeatures;
|
|
16
|
-
const minify = process.env.NODE_ENV === 'production';
|
|
17
|
-
|
|
18
|
-
const featureDig = Object.keys(features)
|
|
19
|
-
.map(name => {
|
|
20
|
-
const { flags = ['gated'] } = features[name];
|
|
21
|
-
const flagStr = flags.join(',');
|
|
22
|
-
|
|
23
|
-
return `${name}-${flagStr}`;
|
|
24
|
-
})
|
|
25
|
-
.join(',');
|
|
26
|
-
|
|
27
|
-
return async (context: ModernServerContext, next: NextFunction) => {
|
|
28
|
-
if (context.url !== route) {
|
|
29
|
-
return next();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const parsedUA = Parser(context.headers['user-agent']);
|
|
33
|
-
const { name = '', version = '' } = parsedUA.browser;
|
|
34
|
-
|
|
35
|
-
const cacheKey = generateCacheKey({
|
|
36
|
-
name,
|
|
37
|
-
version,
|
|
38
|
-
features: featureDig,
|
|
39
|
-
minify,
|
|
40
|
-
});
|
|
41
|
-
const matched = cache.get(cacheKey);
|
|
42
|
-
if (matched) {
|
|
43
|
-
context.res.setHeader(
|
|
44
|
-
'content-type',
|
|
45
|
-
mime.contentType('js') as string,
|
|
46
|
-
);
|
|
47
|
-
return context.res.end(matched);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const polyfill = await getPolyfillString({
|
|
51
|
-
uaString: context.headers['user-agent'] as string,
|
|
52
|
-
minify,
|
|
53
|
-
features,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
cache.set(cacheKey, polyfill);
|
|
57
|
-
|
|
58
|
-
context.res.setHeader('content-type', mime.contentType('js') as string);
|
|
59
|
-
return context.res.end(polyfill);
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
}),
|
|
63
|
-
{
|
|
64
|
-
name: '@modern-js/plugin-polyfill',
|
|
65
|
-
},
|
|
66
|
-
) as any;
|
package/src/libs/cache.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import LRUCache from 'lru-cache';
|
|
3
|
-
|
|
4
|
-
type CacheQueryOptions = {
|
|
5
|
-
features: string;
|
|
6
|
-
minify: boolean;
|
|
7
|
-
name: string;
|
|
8
|
-
version: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const KB = 1024;
|
|
12
|
-
const MB = 1024 * KB;
|
|
13
|
-
|
|
14
|
-
const keyCache = new LRUCache<string, string>(10000);
|
|
15
|
-
export const generateCacheKey = (options: CacheQueryOptions) => {
|
|
16
|
-
const { name, version, features, minify } = options;
|
|
17
|
-
|
|
18
|
-
const str = `${name}-${version}-${Number(minify)}-${features}`;
|
|
19
|
-
const matched = keyCache.get(str);
|
|
20
|
-
if (matched) {
|
|
21
|
-
return matched;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const hash = crypto
|
|
25
|
-
.createHmac('sha256', '^polyfill$')
|
|
26
|
-
.update(str)
|
|
27
|
-
.digest('hex');
|
|
28
|
-
keyCache.set(str, hash);
|
|
29
|
-
return hash;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default class Cache {
|
|
33
|
-
private readonly caches: LRUCache<string, string>;
|
|
34
|
-
|
|
35
|
-
constructor() {
|
|
36
|
-
this.caches = new LRUCache({
|
|
37
|
-
max: 200 * MB,
|
|
38
|
-
length: v => v.length,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public get(hash: string) {
|
|
43
|
-
return this.caches.get(hash);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public set(hash: string, content: string) {
|
|
47
|
-
this.caches.set(hash, content);
|
|
48
|
-
}
|
|
49
|
-
}
|