vite-plugin-blocklet 0.8.16 → 0.9.0

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/dist/index.cjs CHANGED
@@ -10,6 +10,10 @@ var util = require('@ocap/util');
10
10
  var did = require('@arcblock/did');
11
11
  var ufo = require('ufo');
12
12
  var isMobile = require('ismobilejs');
13
+ var path = require('node:path');
14
+ var mlly = require('mlly');
15
+ var externalGlobals = require('rollup-plugin-external-globals');
16
+ var pMap = require('p-map');
13
17
  var getPort = require('get-port');
14
18
  var mri = require('mri');
15
19
  var httpProxyMiddleware = require('http-proxy-middleware');
@@ -477,6 +481,144 @@ function createExpressPlugin({ entryPath, ignorePath = [] }) {
477
481
  };
478
482
  }
479
483
 
484
+ const DEFINE_KEY = '__UNDER_BLOCKLET_EMBED_BUNDLE__';
485
+ const PROXY_SUFFIX = 'blocklet-embed-proxy';
486
+ const ENTRY_FILE = 'index.mjs';
487
+ const defaultExternals = [
488
+ // default externals
489
+ 'react',
490
+ '@arcblock/ux/lib/Locale/context',
491
+ '@arcblock/did-connect/lib/Session',
492
+ ];
493
+
494
+ /**
495
+ * @param {object} options - The options for the plugin.
496
+ * @param {object} [options.embeds={}] - The embeds to be built.
497
+ * @param {array} [options.embedExternals=['react', '@arcblock/ux/lib/Locale/context', '@arcblock/did-connect/lib/Session']] - The external modules to be used in the embeds.
498
+ * @param {array} [options.embedPlugins=[]] - The plugins to be used in the embeds.
499
+ * @param {number} [options.embedBuildConcurrency=0] - The plugins to be used in the embeds.
500
+ * @return {array} The Vite config plugin.
501
+ */
502
+ function createEmbedPlugin(options) {
503
+ const cache = {
504
+ config: {},
505
+ };
506
+
507
+ const inputEmbeds = options?.embeds || [];
508
+ const embedBuildConcurrency = options?.embedBuildConcurrency || 0;
509
+ let embedList = inputEmbeds;
510
+ if (!Array.isArray(inputEmbeds)) {
511
+ embedList = Object.keys(inputEmbeds).map((key) => {
512
+ return {
513
+ output: key,
514
+ entry: inputEmbeds[key],
515
+ };
516
+ });
517
+ }
518
+
519
+ return [
520
+ {
521
+ name: 'blocklet:embed:serve',
522
+ apply: 'serve',
523
+ enforce: 'pre',
524
+ async resolveId(id, importer, options) {
525
+ const queryObject = ufo.getQuery(id);
526
+ if (queryObject[PROXY_SUFFIX] !== undefined) {
527
+ return id;
528
+ }
529
+ const entryId = ufo.parseURL(id).pathname;
530
+ const embedInput = embedList.find((x) => ufo.joinURL(ufo.withLeadingSlash(x.output), ENTRY_FILE) === entryId);
531
+ console.log('embedInput', embedInput);
532
+ if (embedInput?.entry) {
533
+ const resolution = await this.resolve(embedInput.entry, importer, options);
534
+ return ufo.withQuery(resolution.id, { [PROXY_SUFFIX]: '' });
535
+ }
536
+ return null;
537
+ },
538
+ async load(id) {
539
+ const queryObject = ufo.getQuery(id);
540
+ if (queryObject[PROXY_SUFFIX] !== undefined) {
541
+ const entryId = ufo.parseURL(id).pathname;
542
+ const fileContent = await node_fs.promises.readFile(entryId, { encoding: 'utf-8' });
543
+ const names = mlly.findExportNames(fileContent);
544
+ let code = `import ${JSON.stringify(entryId)};`;
545
+ code += `export * from ${JSON.stringify(entryId)};`;
546
+ if (names.includes('default')) {
547
+ code += `export { default } from ${JSON.stringify(entryId)};`;
548
+ }
549
+ return code;
550
+ }
551
+ return null;
552
+ },
553
+ },
554
+ {
555
+ name: 'blocklet:embed:build',
556
+ apply: 'build',
557
+ enforce: 'post',
558
+ config(config) {
559
+ cache.config = config;
560
+ },
561
+ async closeBundle() {
562
+ if (cache.config?.define?.[DEFINE_KEY]) {
563
+ return;
564
+ }
565
+
566
+ const external = options?.embedExternals ? options.embedExternals : defaultExternals;
567
+ const externalMaps = external.reduce((acc, cur) => {
568
+ acc[cur] = `window[Symbol.for('embedModules')]['${cur}']`;
569
+ return acc;
570
+ }, {});
571
+
572
+ const promiseList = pMap(
573
+ embedList,
574
+ async (embedItem) => {
575
+ const entryItem = embedItem.entry;
576
+ const outputItem = ufo.withoutLeadingSlash(embedItem.output);
577
+ // eslint-disable-next-line no-await-in-loop
578
+ await vite.build({
579
+ ...cache.config,
580
+ configFile: false,
581
+ publicDir: false,
582
+ define: {
583
+ ...cache.config?.define,
584
+ 'process.env': {
585
+ NODE_ENV: 'production',
586
+ ...(cache.config?.define?.['process.env'] || {}),
587
+ },
588
+ [DEFINE_KEY]: true,
589
+ },
590
+ plugins: [
591
+ ...(cache.config?.plugins || []),
592
+ ...(options?.embedPlugins || []),
593
+ externalGlobals(externalMaps),
594
+ ],
595
+ build: {
596
+ lib: {
597
+ entry: entryItem,
598
+ formats: ['es'],
599
+ fileName: path.parse(ENTRY_FILE).name,
600
+ },
601
+ rollupOptions: {
602
+ external,
603
+ output: {
604
+ dir: ufo.joinURL(cache.config?.build?.outDir || 'dist', outputItem),
605
+ },
606
+ },
607
+ },
608
+ });
609
+ },
610
+ {
611
+ concurrency: embedBuildConcurrency || 1,
612
+ },
613
+ );
614
+ if (embedBuildConcurrency === 0) {
615
+ await promiseList;
616
+ }
617
+ },
618
+ },
619
+ ];
620
+ }
621
+
480
622
  const argv = process.argv.slice(2);
481
623
  const isProduction = process.env.NODE_ENV === 'production' || process.env.ABT_NODE_SERVICE_ENV === 'production';
482
624
 
@@ -585,6 +727,7 @@ async function setupClient(app, options = {}) {
585
727
  * @property {boolean} [disableHmr=false] - Disable hmr plugin.
586
728
  * @property {boolean} [disableLoading=false] - Disable loading plugin.
587
729
  * @property {boolean} [disableDebug=false] - Disable debug plugin.
730
+ * @property {boolean} [disableEmbed=false] - Disable embed plugin.
588
731
  * @property {import('vite-plugin-node-polyfills').PolyfillOptions} [nodePolyfillsOptions]
589
732
  *
590
733
  * @property {string} [loadingElementId]
@@ -592,6 +735,10 @@ async function setupClient(app, options = {}) {
592
735
  * @property {string} [loadingImage]
593
736
  * @property {'all'|'mobile'|'desktop'} [debugPlatform='mobile']
594
737
  * @property {string} [debugScript]
738
+ * @param {object} [embeds={}] - The embeds to be built.
739
+ * @param {array} [embedExternals=['react', '@arcblock/ux/lib/Locale/context', '@arcblock/did-connect/lib/Session']] - The external modules to be used in the embeds.
740
+ * @param {array} [embedPlugins=[]] - The plugins to be used in the embeds.
741
+ * @param {number} [embedBuildConcurrency=0] - The plugins to be used in the embeds.
595
742
  * @property {'middleware'|'client'|'server'|'wsUpgrade'} [hmrMode='middleware'] - 当未传入任何 option 参数时,会自动变为 middleware 模式
596
743
  */
597
744
 
@@ -611,6 +758,7 @@ function createBlockletPlugin(options = {}) {
611
758
  disableHmr = false,
612
759
  disableLoading = false,
613
760
  disableDebug = false,
761
+ disableEmbed = false,
614
762
  nodePolyfillsOptions,
615
763
  ...restOptions
616
764
  } = options;
@@ -636,6 +784,9 @@ function createBlockletPlugin(options = {}) {
636
784
  if (!disableDebug) {
637
785
  plugins.push(createConfigPlugin(restOptions));
638
786
  }
787
+ if (!disableEmbed) {
788
+ plugins.push(createEmbedPlugin(restOptions));
789
+ }
639
790
 
640
791
  return plugins;
641
792
  }
@@ -646,6 +797,7 @@ Object.defineProperty(exports, "nodePolyfills", {
646
797
  });
647
798
  exports.createBlockletConfig = createConfigPlugin$1;
648
799
  exports.createBlockletDebug = createConfigPlugin;
800
+ exports.createBlockletEmbed = createEmbedPlugin;
649
801
  exports.createBlockletExpress = createExpressPlugin;
650
802
  exports.createBlockletHmr = createHmrPlugin;
651
803
  exports.createBlockletLoading = createLoadingPlugin;
package/index.js CHANGED
@@ -5,6 +5,7 @@ import createMetaPlugin from './libs/meta.js';
5
5
  import createLoadingPlugin from './libs/loading.js';
6
6
  import createDebugPlugin from './libs/debug.js';
7
7
  import createExpressPlugin from './libs/express.js';
8
+ import createEmbedPlugin from './libs/embed.js';
8
9
  import setupClient from './libs/client.js';
9
10
 
10
11
  /**
@@ -17,6 +18,7 @@ import setupClient from './libs/client.js';
17
18
  * @property {boolean} [disableHmr=false] - Disable hmr plugin.
18
19
  * @property {boolean} [disableLoading=false] - Disable loading plugin.
19
20
  * @property {boolean} [disableDebug=false] - Disable debug plugin.
21
+ * @property {boolean} [disableEmbed=false] - Disable embed plugin.
20
22
  * @property {import('vite-plugin-node-polyfills').PolyfillOptions} [nodePolyfillsOptions]
21
23
  *
22
24
  * @property {string} [loadingElementId]
@@ -24,6 +26,10 @@ import setupClient from './libs/client.js';
24
26
  * @property {string} [loadingImage]
25
27
  * @property {'all'|'mobile'|'desktop'} [debugPlatform='mobile']
26
28
  * @property {string} [debugScript]
29
+ * @param {object} [embeds={}] - The embeds to be built.
30
+ * @param {array} [embedExternals=['react', '@arcblock/ux/lib/Locale/context', '@arcblock/did-connect/lib/Session']] - The external modules to be used in the embeds.
31
+ * @param {array} [embedPlugins=[]] - The plugins to be used in the embeds.
32
+ * @param {number} [embedBuildConcurrency=0] - The plugins to be used in the embeds.
27
33
  * @property {'middleware'|'client'|'server'|'wsUpgrade'} [hmrMode='middleware'] - 当未传入任何 option 参数时,会自动变为 middleware 模式
28
34
  */
29
35
 
@@ -43,6 +49,7 @@ export function createBlockletPlugin(options = {}) {
43
49
  disableHmr = false,
44
50
  disableLoading = false,
45
51
  disableDebug = false,
52
+ disableEmbed = false,
46
53
  nodePolyfillsOptions,
47
54
  ...restOptions
48
55
  } = options;
@@ -68,6 +75,9 @@ export function createBlockletPlugin(options = {}) {
68
75
  if (!disableDebug) {
69
76
  plugins.push(createDebugPlugin(restOptions));
70
77
  }
78
+ if (!disableEmbed) {
79
+ plugins.push(createEmbedPlugin(restOptions));
80
+ }
71
81
 
72
82
  return plugins;
73
83
  }
@@ -80,5 +90,6 @@ export {
80
90
  createLoadingPlugin as createBlockletLoading,
81
91
  createDebugPlugin as createBlockletDebug,
82
92
  createExpressPlugin as createBlockletExpress,
93
+ createEmbedPlugin as createBlockletEmbed,
83
94
  nodePolyfills,
84
95
  };
package/libs/embed.js ADDED
@@ -0,0 +1,145 @@
1
+ import path from 'node:path';
2
+ import { promises as fs } from 'node:fs';
3
+ import { findExportNames } from 'mlly';
4
+ import externalGlobals from 'rollup-plugin-external-globals';
5
+ import { joinURL, withLeadingSlash, withoutLeadingSlash, getQuery, withQuery, parseURL } from 'ufo';
6
+ import { build } from 'vite';
7
+ import pMap from 'p-map';
8
+
9
+ const DEFINE_KEY = '__UNDER_BLOCKLET_EMBED_BUNDLE__';
10
+ const PROXY_SUFFIX = 'blocklet-embed-proxy';
11
+ const ENTRY_FILE = 'index.mjs';
12
+ const defaultExternals = [
13
+ // default externals
14
+ 'react',
15
+ '@arcblock/ux/lib/Locale/context',
16
+ '@arcblock/did-connect/lib/Session',
17
+ ];
18
+
19
+ /**
20
+ * @param {object} options - The options for the plugin.
21
+ * @param {object} [options.embeds={}] - The embeds to be built.
22
+ * @param {array} [options.embedExternals=['react', '@arcblock/ux/lib/Locale/context', '@arcblock/did-connect/lib/Session']] - The external modules to be used in the embeds.
23
+ * @param {array} [options.embedPlugins=[]] - The plugins to be used in the embeds.
24
+ * @param {number} [options.embedBuildConcurrency=0] - The plugins to be used in the embeds.
25
+ * @return {array} The Vite config plugin.
26
+ */
27
+ export default function createEmbedPlugin(options) {
28
+ const cache = {
29
+ config: {},
30
+ };
31
+
32
+ const inputEmbeds = options?.embeds || [];
33
+ const embedBuildConcurrency = options?.embedBuildConcurrency || 0;
34
+ let embedList = inputEmbeds;
35
+ if (!Array.isArray(inputEmbeds)) {
36
+ embedList = Object.keys(inputEmbeds).map((key) => {
37
+ return {
38
+ output: key,
39
+ entry: inputEmbeds[key],
40
+ };
41
+ });
42
+ }
43
+
44
+ return [
45
+ {
46
+ name: 'blocklet:embed:serve',
47
+ apply: 'serve',
48
+ enforce: 'pre',
49
+ async resolveId(id, importer, options) {
50
+ const queryObject = getQuery(id);
51
+ if (queryObject[PROXY_SUFFIX] !== undefined) {
52
+ return id;
53
+ }
54
+ const entryId = parseURL(id).pathname;
55
+ const embedInput = embedList.find((x) => joinURL(withLeadingSlash(x.output), ENTRY_FILE) === entryId);
56
+ console.log('embedInput', embedInput);
57
+ if (embedInput?.entry) {
58
+ const resolution = await this.resolve(embedInput.entry, importer, options);
59
+ return withQuery(resolution.id, { [PROXY_SUFFIX]: '' });
60
+ }
61
+ return null;
62
+ },
63
+ async load(id) {
64
+ const queryObject = getQuery(id);
65
+ if (queryObject[PROXY_SUFFIX] !== undefined) {
66
+ const entryId = parseURL(id).pathname;
67
+ const fileContent = await fs.readFile(entryId, { encoding: 'utf-8' });
68
+ const names = findExportNames(fileContent);
69
+ let code = `import ${JSON.stringify(entryId)};`;
70
+ code += `export * from ${JSON.stringify(entryId)};`;
71
+ if (names.includes('default')) {
72
+ code += `export { default } from ${JSON.stringify(entryId)};`;
73
+ }
74
+ return code;
75
+ }
76
+ return null;
77
+ },
78
+ },
79
+ {
80
+ name: 'blocklet:embed:build',
81
+ apply: 'build',
82
+ enforce: 'post',
83
+ config(config) {
84
+ cache.config = config;
85
+ },
86
+ async closeBundle() {
87
+ if (cache.config?.define?.[DEFINE_KEY]) {
88
+ return;
89
+ }
90
+
91
+ const external = options?.embedExternals ? options.embedExternals : defaultExternals;
92
+ const externalMaps = external.reduce((acc, cur) => {
93
+ acc[cur] = `window[Symbol.for('embedModules')]['${cur}']`;
94
+ return acc;
95
+ }, {});
96
+
97
+ const promiseList = pMap(
98
+ embedList,
99
+ async (embedItem) => {
100
+ const entryItem = embedItem.entry;
101
+ const outputItem = withoutLeadingSlash(embedItem.output);
102
+ // eslint-disable-next-line no-await-in-loop
103
+ await build({
104
+ ...cache.config,
105
+ configFile: false,
106
+ publicDir: false,
107
+ define: {
108
+ ...cache.config?.define,
109
+ 'process.env': {
110
+ NODE_ENV: 'production',
111
+ ...(cache.config?.define?.['process.env'] || {}),
112
+ },
113
+ [DEFINE_KEY]: true,
114
+ },
115
+ plugins: [
116
+ ...(cache.config?.plugins || []),
117
+ ...(options?.embedPlugins || []),
118
+ externalGlobals(externalMaps),
119
+ ],
120
+ build: {
121
+ lib: {
122
+ entry: entryItem,
123
+ formats: ['es'],
124
+ fileName: path.parse(ENTRY_FILE).name,
125
+ },
126
+ rollupOptions: {
127
+ external,
128
+ output: {
129
+ dir: joinURL(cache.config?.build?.outDir || 'dist', outputItem),
130
+ },
131
+ },
132
+ },
133
+ });
134
+ },
135
+ {
136
+ concurrency: embedBuildConcurrency || 1,
137
+ },
138
+ );
139
+ if (embedBuildConcurrency === 0) {
140
+ await promiseList;
141
+ }
142
+ },
143
+ },
144
+ ];
145
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-blocklet",
3
3
  "type": "module",
4
- "version": "0.8.16",
4
+ "version": "0.9.0",
5
5
  "description": "",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -24,7 +24,7 @@
24
24
  "author": "",
25
25
  "license": "ISC",
26
26
  "devDependencies": {
27
- "rollup": "^4.18.0"
27
+ "rollup": "^4.20.0"
28
28
  },
29
29
  "dependencies": {
30
30
  "@arcblock/did": "^1.18.128",
@@ -33,11 +33,14 @@
33
33
  "get-port": "^5.1.1",
34
34
  "http-proxy-middleware": "^3.0.0",
35
35
  "ismobilejs": "^1.1.1",
36
+ "mlly": "^1.7.1",
36
37
  "mri": "^1.2.0",
37
- "semver": "^7.6.2",
38
- "ufo": "^1.5.3",
38
+ "p-map": "^4.0.0",
39
+ "rollup-plugin-external-globals": "^0.12.0",
40
+ "semver": "^7.6.3",
41
+ "ufo": "^1.5.4",
39
42
  "vite-plugin-node-polyfills": "^0.22.0",
40
- "yaml": "^2.4.5"
43
+ "yaml": "^2.5.0"
41
44
  },
42
45
  "peerDependencies": {
43
46
  "vite": ">=5"