@into-mini/sfc-split-plugin 0.1.1 → 0.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@into-mini/sfc-split-plugin",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "keywords": [
6
6
  "loader",
@@ -32,13 +32,14 @@
32
32
  "slash": "^5.1.0",
33
33
  "webpack-virtual-modules": "^0.6.2",
34
34
  "yaml": "^2.8.2",
35
- "yaml-patch-loader": "^0.1.0",
35
+ "@into-mini/clsx": "^0.1.0",
36
36
  "@into-mini/sfc-transformer": "^0.5.12",
37
- "@into-mini/wxml-loader": "^0.0.0",
38
- "@into-mini/clsx": "^0.1.0"
37
+ "@into-mini/sfc-split-loader": "^0.0.0",
38
+ "@into-mini/wxml-loader": "^0.0.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@babel/core": "^7.28.5",
42
+ "mini-css-extract-plugin": "^2.9.4",
42
43
  "webpack": "^5.103.0"
43
44
  },
44
45
  "engines": {
@@ -0,0 +1,109 @@
1
+ /* eslint-disable no-continue */
2
+ import path from 'node:path';
3
+
4
+ const pluginName = 'EntryRenamePlugin';
5
+
6
+ export class EntryRenamePlugin {
7
+ options;
8
+
9
+ constructor(options = {}) {
10
+ this.options = options;
11
+ }
12
+
13
+ getIssuerPath(issuerModule) {
14
+ return (
15
+ issuerModule?.nameForCondition?.() ??
16
+ issuerModule?.resource ??
17
+ issuerModule?.identifier?.()
18
+ );
19
+ }
20
+
21
+ matchIssuer(issuerPath) {
22
+ const { issuer } = this.options;
23
+
24
+ if (!issuer) {
25
+ return true;
26
+ }
27
+
28
+ if (!issuerPath) {
29
+ return false;
30
+ }
31
+
32
+ if (issuer instanceof RegExp) {
33
+ return issuer.test(issuerPath);
34
+ }
35
+
36
+ if (typeof issuer === 'function') {
37
+ return issuer(issuerPath);
38
+ }
39
+
40
+ return issuerPath.includes(issuer);
41
+ }
42
+
43
+ matchTest(filename) {
44
+ const { test } = this.options;
45
+
46
+ if (!test) {
47
+ return true;
48
+ }
49
+
50
+ if (test instanceof RegExp) {
51
+ return test.test(filename);
52
+ }
53
+
54
+ if (typeof test === 'function') {
55
+ return test(filename);
56
+ }
57
+
58
+ return filename.includes(test);
59
+ }
60
+
61
+ apply(compiler) {
62
+ compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
63
+ const { Compilation } = compiler.webpack;
64
+ compilation.hooks.processAssets.tap(
65
+ { name: pluginName, stage: Compilation.PROCESS_ASSETS_STAGE_ADDITIONS },
66
+ () => {
67
+ for (const module of compilation.modules) {
68
+ const filename = module.buildInfo?.filename;
69
+
70
+ if (!filename) {
71
+ continue;
72
+ }
73
+
74
+ if (!this.matchTest(filename)) {
75
+ continue;
76
+ }
77
+
78
+ const issuerModule = compilation.moduleGraph.getIssuer(module);
79
+ const issuerPath = this.getIssuerPath(issuerModule);
80
+
81
+ if (!this.matchIssuer(issuerPath)) {
82
+ continue;
83
+ }
84
+
85
+ const chunks = compilation.chunkGraph.getModuleChunks(module);
86
+ const entryChunk = [...chunks].find((chunk) => chunk.name);
87
+
88
+ if (!entryChunk?.name) {
89
+ continue;
90
+ }
91
+
92
+ const ext = path.extname(filename);
93
+ const newName = `${entryChunk.name}${ext}`;
94
+
95
+ if (newName === filename) {
96
+ continue;
97
+ }
98
+
99
+ if (compilation.getAsset(newName)) {
100
+ continue;
101
+ }
102
+
103
+ compilation.renameAsset(filename, newName);
104
+ }
105
+ },
106
+ );
107
+ });
108
+ }
109
+ }
@@ -1,11 +1,15 @@
1
1
  import slash from 'slash';
2
+
2
3
  const PLUGIN_NAME = 'ExposeEntryNamePlugin';
4
+
3
5
  export class ExposeEntryNamePlugin {
4
6
  getEntryNameFromEntries(compilation, module) {
5
7
  const { moduleGraph, entries } = compilation;
8
+
6
9
  for (const [name, io] of entries) {
7
10
  for (const dep of io.dependencies) {
8
11
  const entryModule = moduleGraph.getModule(dep);
12
+
9
13
  if (entryModule) {
10
14
  if (
11
15
  // @ts-expect-error ------------
@@ -14,6 +18,7 @@ export class ExposeEntryNamePlugin {
14
18
  ) {
15
19
  return name;
16
20
  }
21
+
17
22
  if (
18
23
  // @ts-expect-error ------------
19
24
  entryModule?.resource && // @ts-expect-error ------------
@@ -24,21 +29,27 @@ export class ExposeEntryNamePlugin {
24
29
  }
25
30
  }
26
31
  }
32
+
27
33
  return '';
28
34
  }
35
+
29
36
  getEntryNameFromPathData(compilation, pathData) {
30
37
  const mod = pathData.module;
31
38
  const graph = pathData.chunkGraph;
39
+
32
40
  if (mod && graph) {
33
41
  const [entryModule] = graph
34
42
  .getModuleChunks(mod)
35
43
  .map((chunk) => [...graph.getChunkEntryModulesIterable(chunk)][0]);
44
+
36
45
  if (entryModule) {
37
46
  return this.getEntryNameFromEntries(compilation, entryModule);
38
47
  }
39
48
  }
49
+
40
50
  return '';
41
51
  }
52
+
42
53
  apply(compiler) {
43
54
  const {
44
55
  NormalModule: { getCompilationHooks },
@@ -50,10 +61,12 @@ export class ExposeEntryNamePlugin {
50
61
  compilation,
51
62
  pathData,
52
63
  );
64
+
53
65
  return entryName
54
66
  ? path.replaceAll('[entry]', entryName)
55
67
  : path.replaceAll('[entry]', '[hash:8]');
56
68
  }
69
+
57
70
  return path;
58
71
  });
59
72
  getCompilationHooks(compilation).loader.tap(
@@ -1,22 +1,29 @@
1
1
  import slash from 'slash';
2
+
2
3
  const PLUGIN_NAME = 'ExposeEntryNamePlugin';
4
+
3
5
  export class ExposeEntryNamePlugin {
4
6
  getEntryNameFromChunk(chunk) {
5
7
  if (!chunk?.groupsIterable) {
6
8
  return '';
7
9
  }
10
+
8
11
  for (const group of chunk.groupsIterable) {
9
12
  if (group.isInitial()) {
10
13
  return group.name;
11
14
  }
12
15
  }
16
+
13
17
  return '';
14
18
  }
19
+
15
20
  getEntryNameFromEntries(compilation, module) {
16
21
  const { moduleGraph, entries } = compilation;
22
+
17
23
  for (const [name, io] of entries) {
18
24
  for (const dep of io.dependencies) {
19
25
  const entryModule = moduleGraph.getModule(dep);
26
+
20
27
  if (entryModule) {
21
28
  if (
22
29
  // @ts-expect-error ------------
@@ -25,6 +32,7 @@ export class ExposeEntryNamePlugin {
25
32
  ) {
26
33
  return name;
27
34
  }
35
+
28
36
  if (
29
37
  // @ts-expect-error ------------
30
38
  entryModule?.resource && // @ts-expect-error ------------
@@ -35,26 +43,34 @@ export class ExposeEntryNamePlugin {
35
43
  }
36
44
  }
37
45
  }
46
+
38
47
  return '';
39
48
  }
49
+
40
50
  getEntryNameFromPathData(pathData) {
41
51
  if (pathData?.chunk) {
42
52
  const entryName = this.getEntryNameFromChunk(pathData.chunk);
53
+
43
54
  if (entryName) {
44
55
  return entryName;
45
56
  }
46
57
  }
58
+
47
59
  if (pathData?.module && pathData?.chunkGraph) {
48
60
  const chunks = pathData.chunkGraph.getModuleChunks(pathData.module);
61
+
49
62
  for (const chunk of chunks) {
50
63
  const entryName = this.getEntryNameFromChunk(chunk);
64
+
51
65
  if (entryName) {
52
66
  return entryName;
53
67
  }
54
68
  }
55
69
  }
70
+
56
71
  return '';
57
72
  }
73
+
58
74
  apply(compiler) {
59
75
  const {
60
76
  NormalModule: { getCompilationHooks },
@@ -63,10 +79,12 @@ export class ExposeEntryNamePlugin {
63
79
  compilation.hooks.assetPath.tap(PLUGIN_NAME, (path, pathData) => {
64
80
  if (path.includes('[entry]')) {
65
81
  const entryName = this.getEntryNameFromPathData(pathData);
82
+
66
83
  return entryName
67
84
  ? path.replaceAll('[entry]', entryName)
68
85
  : path.replaceAll('[entry]', '[hash:8]');
69
86
  }
87
+
70
88
  return path;
71
89
  });
72
90
  getCompilationHooks(compilation).loader.tap(
@@ -4,8 +4,8 @@ import { parse } from '@into-mini/sfc-transformer';
4
4
  import slash from 'slash';
5
5
  import VirtualModulesPlugin from 'webpack-virtual-modules';
6
6
 
7
- export class SfcSplitPlugin extends VirtualModulesPlugin {
8
- PLUGIN_NAME = 'SfcSplitPlugin';
7
+ export class SfcSplitPluginBase extends VirtualModulesPlugin {
8
+ PLUGIN_NAME = 'SfcSplitPluginBase';
9
9
 
10
10
  constructor({ tagMatcher, preserveTap }) {
11
11
  super();
package/plugin.mjs CHANGED
@@ -1,22 +1,18 @@
1
- /* eslint-disable no-param-reassign */
2
1
  import { fileURLToPath } from 'node:url';
3
2
 
4
- import { COMPONENT_ROOT } from './helper/index.mjs';
5
- import { configKeys } from './helper/utils.mjs';
6
- import { AddEntryPlugin } from './plugin/add-entry.mjs';
7
3
  import { AddWxsPlugin } from './plugin/add-wxs.mjs';
8
- import { CopyConfigPlugin } from './plugin/copy-config.mjs';
9
- import { EmitFakePlugin } from './plugin/emit-fake.mjs';
10
4
  import { ExposeEntryNamePlugin } from './plugin/expose-entry.mjs';
11
- import { FindEntryPlugin } from './plugin/find-entry.mjs';
12
- import { SfcSplitPlugin } from './plugin/sfc-split.mjs';
5
+ // import { EntryRenamePlugin } from './plugin/entry-rename.mjs';
6
+ import { SfcSplitPluginBase } from './plugin/sfc-split.mjs';
13
7
  import { MinaRuntimeWebpackPlugin } from './plugin/mina-runtime.mjs';
14
8
 
9
+ export const COMPONENT_ROOT = 'as-components';
10
+
15
11
  function reach(path) {
16
12
  return fileURLToPath(import.meta.resolve(path));
17
13
  }
18
14
 
19
- export class AllInOnePlugin {
15
+ export class SfcSplitPlugin {
20
16
  constructor({ type = false, tagMatcher, preserveTap } = {}) {
21
17
  this.type = type;
22
18
  this.tagMatcher = tagMatcher;
@@ -42,55 +38,25 @@ export class AllInOnePlugin {
42
38
  loader: reach('@into-mini/wxml-loader'),
43
39
  generator: {
44
40
  filename: '[entry][ext]',
41
+ // filename: '[contenthash:8][ext]',
45
42
  },
46
43
  },
47
- {
48
- test: /\.hack$/,
49
- type: 'javascript/esm',
50
- layer: configKeys.hack,
51
- loader: reach('./loader/hack-entry-loader.mjs'),
52
- },
53
44
  );
54
45
  }
55
46
 
56
- #prepare(compiler) {
57
- compiler.options.resolve.extensionAlias ??= {};
58
-
59
- compiler.options.resolve.extensionAlias['.yaml'] = [
60
- '.yaml',
61
- '.yml',
62
- '.json',
63
- ];
64
-
65
- compiler.options.resolve.fallback ??= {};
66
-
67
- if (compiler.options.entry?.main) {
68
- delete compiler.options.entry.main;
69
- }
70
-
71
- Object.assign(compiler, {
72
- __entries__: new Map(),
73
- });
74
- }
75
-
76
47
  apply(compiler) {
77
- this.#prepare(compiler);
78
48
  this.#applyLoader(compiler);
79
49
 
80
50
  const { type, tagMatcher, preserveTap } = this;
81
51
 
82
52
  if (type) {
83
- new MinaRuntimeWebpackPlugin().apply(compiler);
84
- new AddEntryPlugin().apply(compiler);
85
53
  new AddWxsPlugin().apply(compiler);
86
- new SfcSplitPlugin({ tagMatcher, preserveTap }).apply(compiler);
54
+ new MinaRuntimeWebpackPlugin().apply(compiler);
55
+ new SfcSplitPluginBase({ tagMatcher, preserveTap }).apply(compiler);
87
56
  new ExposeEntryNamePlugin().apply(compiler);
88
- new FindEntryPlugin({ type }).apply(compiler);
89
- new CopyConfigPlugin({ type }).apply(compiler);
90
- }
91
-
92
- if (type === 'miniprogram') {
93
- new EmitFakePlugin().apply(compiler);
57
+ // new EntryRenamePlugin({ issuer: /\.vue$/, test: /\.wxml/ }).apply(
58
+ // compiler,
59
+ // );
94
60
  }
95
61
  }
96
62
  }
package/helper/hooks.mjs DELETED
@@ -1,48 +0,0 @@
1
- import { toJSONString } from '@into-mini/sfc-transformer/utils.mjs';
2
-
3
- import { readConfig } from './read.mjs';
4
-
5
- export function createEmitFile({ PLUGIN_NAME, compilation, RawSource }) {
6
- return (name, content) => {
7
- compilation.hooks.processAssets.tap(
8
- {
9
- name: PLUGIN_NAME,
10
- stage: compilation.constructor.PROCESS_ASSETS_STAGE_ADDITIONAL,
11
- },
12
- () => {
13
- compilation.emitAsset(
14
- name,
15
- new RawSource(
16
- typeof content === 'string' ? content : toJSONString(content),
17
- ),
18
- );
19
- },
20
- );
21
- };
22
- }
23
-
24
- export function readAndTrack(compiler, compilation) {
25
- return (name) => {
26
- const { filePath, config = {} } = readConfig(compiler.context, name);
27
-
28
- if (filePath) {
29
- compilation.fileDependencies.add(filePath);
30
- }
31
-
32
- return {
33
- name: `${name}.json`,
34
- content: config,
35
- empty: Object.keys(config).length === 0,
36
- };
37
- };
38
- }
39
-
40
- export function createAddEntry(compiler) {
41
- return (name, path) => {
42
- new compiler.webpack.EntryPlugin(compiler.context, path, {
43
- import: [path],
44
- name,
45
- // layer: 'base',
46
- }).apply(compiler);
47
- };
48
- }
package/helper/index.mjs DELETED
@@ -1,62 +0,0 @@
1
- export const COMPONENT_ROOT = 'as-components';
2
-
3
- function unique(...arr) {
4
- return [...new Set(arr)];
5
- }
6
-
7
- export function getAllPages(config) {
8
- const { entryPagePath, pages, subPackages, tabBar } = config ?? {};
9
-
10
- const { custom = false, list = [] } = tabBar ?? {};
11
-
12
- return unique(
13
- entryPagePath,
14
- ...(pages ?? []),
15
- ...list.map(({ pagePath }) => pagePath),
16
- ...(subPackages ?? []).flatMap(
17
- (subPackage) =>
18
- (subPackage.pages || []).map((page) => `${subPackage.root}/${page}`) ||
19
- [],
20
- ),
21
- custom === true ? 'custom-tab-bar/index' : '',
22
- ).filter(Boolean);
23
- }
24
-
25
- export function patchConfig(json) {
26
- const object = structuredClone(json ?? {});
27
-
28
- object.pages ??= [];
29
-
30
- if (object.tabBar?.list?.length > 0) {
31
- for (const tab of object.tabBar.list) {
32
- if (tab.pagePath && !object.pages.includes(tab.pagePath)) {
33
- object.pages.push(tab.pagePath);
34
- }
35
- }
36
- }
37
-
38
- object.subPackages ??= [];
39
- object.preloadRule ??= {};
40
-
41
- for (const page of object.pages) {
42
- object.preloadRule[page] ??= {};
43
-
44
- object.preloadRule[page].network = 'all';
45
- object.preloadRule[page].packages ??= [];
46
-
47
- if (!object.preloadRule[page].packages.includes(COMPONENT_ROOT)) {
48
- object.preloadRule[page].packages.push(COMPONENT_ROOT);
49
- }
50
- }
51
-
52
- if (
53
- !object.subPackages.some((subPackage) => subPackage.root === COMPONENT_ROOT)
54
- ) {
55
- object.subPackages.push({
56
- root: COMPONENT_ROOT,
57
- pages: ['fake'],
58
- });
59
- }
60
-
61
- return object;
62
- }
package/helper/read.mjs DELETED
@@ -1,37 +0,0 @@
1
- import { readFileSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
-
4
- import { parse as yamlParse } from 'yaml';
5
-
6
- function tryReadFileWithParsers(base, name, ext, parser) {
7
- const filePath = resolve(base, `${name}${ext}`);
8
-
9
- try {
10
- const content = readFileSync(filePath, 'utf8');
11
-
12
- return {
13
- filePath,
14
- config: (parser ? parser(content) : content) || {},
15
- };
16
- } catch {
17
- return false;
18
- }
19
- }
20
-
21
- const candidates = [
22
- { ext: '.yaml', parser: yamlParse },
23
- { ext: '.yml', parser: yamlParse },
24
- { ext: '.json', parser: JSON.parse },
25
- ];
26
-
27
- export function readConfig(base, name) {
28
- for (const { ext, parser } of candidates) {
29
- const result = tryReadFileWithParsers(base, name, ext, parser);
30
-
31
- if (result !== false) {
32
- return result;
33
- }
34
- }
35
-
36
- return false;
37
- }
package/helper/utils.mjs DELETED
@@ -1,6 +0,0 @@
1
- export const configKeys = {
2
- app: 'app-json',
3
- projectPrivate: 'project.private.config',
4
- project: 'project.config',
5
- hack: 'hack.entry',
6
- };
@@ -1,5 +0,0 @@
1
- export default function loader() {
2
- console.log(this._compiler.__entries__);
3
-
4
- return '';
5
- }
@@ -1,85 +0,0 @@
1
- export class AddEntryPlugin {
2
- PLUGIN_NAME = 'AddEntryPlugin';
3
-
4
- #addSmartEntry({ name, path, layer }) {
5
- if (this.compiler.__entries__.get(name) !== path) {
6
- this.compiler.__entries__.set(name, { path, layer });
7
- }
8
- }
9
-
10
- #addEntries(compilation) {
11
- const { compiler } = this;
12
-
13
- const { createDependency } = compiler.webpack.EntryPlugin;
14
-
15
- compilation.hooks.buildModule.tap(this.PLUGIN_NAME, () => {
16
- for (const [name, { path, layer }] of compiler.__entries__.entries()) {
17
- compilation.addEntry(
18
- compiler.context,
19
- createDependency(path, { name }),
20
- {
21
- name,
22
- import: [path],
23
- layer,
24
- },
25
- (err) => {
26
- if (err) {
27
- throw err;
28
- } else {
29
- compilation.fileDependencies.add(path);
30
- }
31
- },
32
- );
33
- }
34
- });
35
- }
36
-
37
- #expose(compiler) {
38
- this.compiler = compiler;
39
-
40
- const { PLUGIN_NAME } = this;
41
-
42
- const {
43
- NormalModule: { getCompilationHooks },
44
- } = compiler.webpack;
45
-
46
- Object.defineProperty(compiler, 'addSmartEntry', {
47
- enumerable: true,
48
- configurable: false,
49
- value: (options) => {
50
- this.#addSmartEntry(options);
51
- },
52
- });
53
-
54
- compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
55
- getCompilationHooks(compilation).loader.tap(
56
- PLUGIN_NAME,
57
- (loaderContext) => {
58
- Object.defineProperty(loaderContext, 'addSmartEntry', {
59
- enumerable: true,
60
- configurable: false,
61
- value: (options) => {
62
- this.#addSmartEntry(options);
63
- },
64
- });
65
- },
66
- );
67
- });
68
- }
69
-
70
- apply(compiler) {
71
- this.#expose(compiler);
72
-
73
- const { PLUGIN_NAME } = this;
74
-
75
- compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
76
- this.#addEntries(compilation);
77
- });
78
- compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
79
- this.#addEntries(compilation);
80
- });
81
- compiler.hooks.make.tap(PLUGIN_NAME, (compilation) => {
82
- this.#addEntries(compilation);
83
- });
84
- }
85
- }
@@ -1,89 +0,0 @@
1
- import { fileURLToPath } from 'node:url';
2
-
3
- import { patchConfig } from '../helper/index.mjs';
4
- import { configKeys } from '../helper/utils.mjs';
5
-
6
- function reach(path) {
7
- return fileURLToPath(import.meta.resolve(path));
8
- }
9
-
10
- const emptyJSON = reach('../helper/empty.json');
11
- const yamlLoader = reach('yaml-patch-loader');
12
-
13
- export class CopyConfigPlugin {
14
- constructor({ type = false } = {}) {
15
- this.type = type;
16
- }
17
-
18
- addConfigSmartEntry({
19
- layer,
20
- from = layer,
21
- name = layer,
22
- filename = from,
23
- options,
24
- }) {
25
- const path = `./${from}.yaml`;
26
-
27
- this.compiler.options.entry[name] = {
28
- import: [path],
29
- layer,
30
- runtime: false,
31
- filename,
32
- };
33
-
34
- this.compiler.options.resolve.fallback[path] = emptyJSON;
35
-
36
- this.compiler.options.module.rules.push({
37
- issuerLayer: layer,
38
- loader: yamlLoader,
39
- type: 'asset/resource',
40
- generator: {
41
- filename: `${filename}.json`,
42
- },
43
- options,
44
- });
45
- }
46
-
47
- apply(compiler) {
48
- const { type } = this;
49
- this.compiler = compiler;
50
-
51
- if (type) {
52
- this.addConfigSmartEntry({
53
- layer: configKeys.project,
54
- options: {
55
- modify: (json) => ({
56
- srcMiniprogramRoot: '',
57
- miniprogramRoot: '',
58
- pluginRoot: '',
59
- ...json,
60
- compileType: type,
61
- }),
62
- },
63
- });
64
-
65
- this.addConfigSmartEntry({
66
- layer: configKeys.projectPrivate,
67
- });
68
-
69
- if (this.type === 'miniprogram') {
70
- this.addConfigSmartEntry({
71
- layer: configKeys.app,
72
- from: 'app',
73
- options: {
74
- modify: patchConfig,
75
- },
76
- });
77
-
78
- this.compiler.options.entry.app = {
79
- import: ['./app'],
80
- };
81
-
82
- // this.compiler.options.entry.__hack__ = {
83
- // import: [reach('../helper/hack.hack')],
84
- // layer: configKeys.hack,
85
- // };
86
- }
87
- }
88
- }
89
- }
@@ -1,35 +0,0 @@
1
- import { COMPONENT_ROOT } from '../helper/index.mjs';
2
-
3
- const files = {
4
- '/fake.json': '{}',
5
- '/fake.js': '/**用于创建分包的假页面**/',
6
- '/fake.wxml': '<!--用于创建分包的假页面-->',
7
- };
8
-
9
- export class EmitFakePlugin {
10
- PLUGIN_NAME = 'EmitFakePlugin';
11
-
12
- apply(compiler) {
13
- const {
14
- sources: { RawSource },
15
- Compilation: { PROCESS_ASSETS_STAGE_ADDITIONAL },
16
- } = compiler.webpack;
17
-
18
- compiler.hooks.make.tap(this.PLUGIN_NAME, (compilation) => {
19
- compilation.hooks.processAssets.tap(
20
- {
21
- name: this.PLUGIN_NAME,
22
- stage: PROCESS_ASSETS_STAGE_ADDITIONAL,
23
- },
24
- () => {
25
- for (const [path, content] of Object.entries(files)) {
26
- compilation.emitAsset(
27
- COMPONENT_ROOT + path,
28
- new RawSource(content),
29
- );
30
- }
31
- },
32
- );
33
- });
34
- }
35
- }
@@ -1,111 +0,0 @@
1
- import { extname } from 'node:path';
2
-
3
- import {
4
- createAddEntry,
5
- createEmitFile,
6
- readAndTrack,
7
- } from '../helper/hooks.mjs';
8
- import { getAllPages } from '../helper/index.mjs';
9
-
10
- /**
11
- * Webpack插件,用于处理小程序和插件的入口文件
12
- */
13
- export class FindEntryPlugin {
14
- PLUGIN_NAME = 'FindEntryPlugin';
15
-
16
- /**
17
- * @param {Object} options - 插件配置选项
18
- * @param {string} [options.type=false] - 项目类型,可选值:'miniprogram'或'plugin'
19
- */
20
- constructor({ type = false } = {}) {
21
- this.type = type;
22
- }
23
-
24
- /**
25
- * 处理Vue页面入口
26
- * @private
27
- */
28
- #handleVuePages(params, pages, basePath = '.') {
29
- const { addEntry, compilation } = params;
30
-
31
- for (const page of pages) {
32
- const source = `${basePath}/${page}.vue`;
33
- addEntry(page, source);
34
- compilation.fileDependencies.add(source);
35
- }
36
- }
37
-
38
- /**
39
- * 处理插件页面和组件
40
- * @private
41
- */
42
- #handlePluginSection(params, config, section) {
43
- const entries = config[section];
44
-
45
- if (!entries) {
46
- return;
47
- }
48
-
49
- Object.entries(entries).forEach(([key, path]) => {
50
- if (typeof path === 'string' && extname(path) === '.vue') {
51
- const source = `${section}/${key}/index`;
52
- params.addEntry(source, path);
53
- params.compilation.fileDependencies.add(path);
54
-
55
- if (section === 'pages') {
56
- config.pages = config.pages || {};
57
- config.pages[key] = source;
58
- }
59
- }
60
- });
61
- }
62
-
63
- /**
64
- * 处理配置和入口
65
- * @private
66
- */
67
- #processConfig(params, configType) {
68
- const { readFrom, emitFile, addEntry, compilation } = params;
69
- const { content: config, name } = readFrom(
70
- configType === 'miniprogram' ? 'app' : configType,
71
- );
72
-
73
- if (configType === 'miniprogram') {
74
- this.#handleVuePages(params, getAllPages(config));
75
- } else if (configType === 'plugin') {
76
- if (config.main) {
77
- addEntry('main', config.main);
78
- compilation.fileDependencies.add(config.main);
79
- config.main = 'main.js';
80
- }
81
-
82
- this.#handlePluginSection(params, config, 'pages');
83
- this.#handlePluginSection(params, config, 'publicComponents');
84
- emitFile(name, config);
85
- }
86
- }
87
-
88
- apply(compiler) {
89
- const {
90
- sources: { RawSource },
91
- } = compiler.webpack;
92
-
93
- const addEntry = createAddEntry(compiler);
94
-
95
- // 处理入口文件和配置
96
- compiler.hooks.compilation.tap(this.PLUGIN_NAME, (compilation) => {
97
- const params = {
98
- compilation,
99
- addEntry,
100
- emitFile: createEmitFile({
101
- PLUGIN_NAME: this.PLUGIN_NAME,
102
- compilation,
103
- RawSource,
104
- }),
105
- readFrom: readAndTrack(compiler, compilation),
106
- };
107
-
108
- this.#processConfig(params, this.type);
109
- });
110
- }
111
- }