@into-mini/sfc-split-plugin 0.1.2 → 0.4.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.
@@ -1,86 +0,0 @@
1
- import slash from 'slash';
2
- const PLUGIN_NAME = 'ExposeEntryNamePlugin';
3
- export class ExposeEntryNamePlugin {
4
- getEntryNameFromChunk(chunk) {
5
- if (!chunk?.groupsIterable) {
6
- return '';
7
- }
8
- for (const group of chunk.groupsIterable) {
9
- if (group.isInitial()) {
10
- return group.name;
11
- }
12
- }
13
- return '';
14
- }
15
- getEntryNameFromEntries(compilation, module) {
16
- const { moduleGraph, entries } = compilation;
17
- for (const [name, io] of entries) {
18
- for (const dep of io.dependencies) {
19
- const entryModule = moduleGraph.getModule(dep);
20
- if (entryModule) {
21
- if (
22
- // @ts-expect-error ------------
23
- entryModule.request && // @ts-expect-error ------------
24
- slash(entryModule.request) === slash(module.request)
25
- ) {
26
- return name;
27
- }
28
- if (
29
- // @ts-expect-error ------------
30
- entryModule?.resource && // @ts-expect-error ------------
31
- slash(entryModule?.resource) === slash(module.resource)
32
- ) {
33
- return name;
34
- }
35
- }
36
- }
37
- }
38
- return '';
39
- }
40
- getEntryNameFromPathData(pathData) {
41
- if (pathData?.chunk) {
42
- const entryName = this.getEntryNameFromChunk(pathData.chunk);
43
- if (entryName) {
44
- return entryName;
45
- }
46
- }
47
- if (pathData?.module && pathData?.chunkGraph) {
48
- const chunks = pathData.chunkGraph.getModuleChunks(pathData.module);
49
- for (const chunk of chunks) {
50
- const entryName = this.getEntryNameFromChunk(chunk);
51
- if (entryName) {
52
- return entryName;
53
- }
54
- }
55
- }
56
- return '';
57
- }
58
- apply(compiler) {
59
- const {
60
- NormalModule: { getCompilationHooks },
61
- } = compiler.webpack;
62
- compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
63
- compilation.hooks.assetPath.tap(PLUGIN_NAME, (path, pathData) => {
64
- if (path.includes('[entry]')) {
65
- const entryName = this.getEntryNameFromPathData(pathData);
66
- return entryName
67
- ? path.replaceAll('[entry]', entryName)
68
- : path.replaceAll('[entry]', '[hash:8]');
69
- }
70
- return path;
71
- });
72
- getCompilationHooks(compilation).loader.tap(
73
- PLUGIN_NAME,
74
- (loaderContext, module) => {
75
- Object.defineProperty(loaderContext, 'entryName', {
76
- enumerable: true,
77
- configurable: false,
78
- get: () => {
79
- return this.getEntryNameFromEntries(compilation, module);
80
- },
81
- });
82
- },
83
- );
84
- });
85
- }
86
- }
@@ -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
- }
@@ -1,58 +0,0 @@
1
- import { dirname, relative, sep } from 'node:path';
2
-
3
- const PLUGIN_NAME = 'MinaRuntimeWebpackPlugin';
4
-
5
- export class MinaRuntimeWebpackPlugin {
6
- // 格式化依赖路径为require语句
7
- #formatRequire = (from, to) =>
8
- `require('./${relative(dirname(from), to).split(sep).join('/')}');\n`;
9
-
10
- // 收集并生成所有依赖的require语句
11
- #generateDependencies = (chunk) => {
12
- if (!chunk?.name) {
13
- return '';
14
- }
15
-
16
- let result = '';
17
-
18
- for (const { chunks } of chunk.groupsIterable) {
19
- for (const depChunk of chunks) {
20
- if (depChunk !== chunk && depChunk.name) {
21
- result += this.#formatRequire(chunk.name, depChunk.name);
22
- }
23
- }
24
- }
25
-
26
- return result;
27
- };
28
-
29
- apply(compiler) {
30
- compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
31
- const {
32
- javascript: { JavascriptModulesPlugin },
33
- sources: { ConcatSource },
34
- } = compiler.webpack;
35
-
36
- JavascriptModulesPlugin.getCompilationHooks(compilation).renderChunk.tap(
37
- PLUGIN_NAME,
38
- (source, { chunk }) => {
39
- if (
40
- !chunk ||
41
- !compilation.chunkGraph.getNumberOfEntryModules(chunk)
42
- ) {
43
- // 跳过非入口模块
44
- return source;
45
- }
46
-
47
- const deps = this.#generateDependencies(chunk);
48
-
49
- if (!deps) {
50
- return source;
51
- }
52
-
53
- return new ConcatSource(deps, source);
54
- },
55
- );
56
- });
57
- }
58
- }
@@ -1,102 +0,0 @@
1
- import path from 'node:path';
2
-
3
- import { parse } from '@into-mini/sfc-transformer';
4
- import slash from 'slash';
5
- import VirtualModulesPlugin from 'webpack-virtual-modules';
6
-
7
- export class SfcSplitPlugin extends VirtualModulesPlugin {
8
- PLUGIN_NAME = 'SfcSplitPlugin';
9
-
10
- constructor({ tagMatcher, preserveTap }) {
11
- super();
12
- this.tagMatcher = tagMatcher;
13
- this.preserveTap = preserveTap;
14
- }
15
-
16
- apply(compiler) {
17
- this.#expose(compiler);
18
-
19
- super.apply(compiler);
20
- }
21
-
22
- #expose(compiler) {
23
- const { PLUGIN_NAME } = this;
24
-
25
- const {
26
- NormalModule: { getCompilationHooks },
27
- } = compiler.webpack;
28
-
29
- compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
30
- getCompilationHooks(compilation).loader.tap(
31
- PLUGIN_NAME,
32
- (loaderContext) => {
33
- Object.defineProperty(loaderContext, 'processSfcFile', {
34
- enumerable: true,
35
- configurable: false,
36
- value: (options) => {
37
- return this.#processSfcFile(options);
38
- },
39
- });
40
- },
41
- );
42
- });
43
- }
44
-
45
- #inject(resourcePath, ext, content) {
46
- const src = path.resolve(resourcePath.replace(/\.vue$/, ext));
47
-
48
- super.writeModule(src, content);
49
-
50
- return src;
51
- }
52
-
53
- #injectStyle(resourcePath, id, style) {
54
- return this.#inject(
55
- resourcePath,
56
- `-${id}.${style.lang ?? 'css'}`,
57
- style.content,
58
- );
59
- }
60
-
61
- #injectStyles(resourcePath, styles) {
62
- const io = [];
63
-
64
- const css = styles?.length > 0 ? styles : [];
65
-
66
- css.forEach((style, idx) => {
67
- if (style?.content) {
68
- const src = this.#injectStyle(resourcePath, idx, style);
69
- io.push(src);
70
- }
71
- });
72
-
73
- return io;
74
- }
75
-
76
- #injectTemplate(resourcePath, tpl) {
77
- return this.#inject(resourcePath, '.wxml', tpl);
78
- }
79
-
80
- #processSfcFile({ source, resourcePath }) {
81
- const { tagMatcher, preserveTap } = this;
82
-
83
- const { tpl, styles, code, config } = parse(source, {
84
- tagMatcher,
85
- preserveTap,
86
- });
87
-
88
- const paths = [];
89
-
90
- const wxml = this.#injectTemplate(resourcePath, tpl);
91
- paths.push(wxml);
92
-
93
- const css = this.#injectStyles(resourcePath, styles);
94
- paths.push(...css);
95
-
96
- return {
97
- config,
98
- paths: paths.map((src) => slash(src)),
99
- script: code,
100
- };
101
- }
102
- }
package/plugin.mjs DELETED
@@ -1,101 +0,0 @@
1
- /* eslint-disable no-param-reassign */
2
- import { fileURLToPath } from 'node:url';
3
-
4
- import { COMPONENT_ROOT } from './helper/index.mjs';
5
- import { configKeys } from './helper/utils.mjs';
6
- import { AddEntryPlugin } from './plugin/add-entry.mjs';
7
- import { AddWxsPlugin } from './plugin/add-wxs.mjs';
8
- import { CopyConfigPlugin } from './plugin/copy-config.mjs';
9
- import { EmitFakePlugin } from './plugin/emit-fake.mjs';
10
- import { ExposeEntryNamePlugin } from './plugin/expose-entry.mjs';
11
- // import { EntryRenamePlugin } from './plugin/entry-rename.mjs';
12
- import { FindEntryPlugin } from './plugin/find-entry.mjs';
13
- import { SfcSplitPlugin } from './plugin/sfc-split.mjs';
14
- import { MinaRuntimeWebpackPlugin } from './plugin/mina-runtime.mjs';
15
-
16
- function reach(path) {
17
- return fileURLToPath(import.meta.resolve(path));
18
- }
19
-
20
- export class AllInOnePlugin {
21
- constructor({ type = false, tagMatcher, preserveTap } = {}) {
22
- this.type = type;
23
- this.tagMatcher = tagMatcher;
24
- this.preserveTap = preserveTap;
25
- }
26
-
27
- #applyLoader(compiler) {
28
- compiler.options.module.rules.push(
29
- // {
30
- // exclude: /\.(vue|wxml)$/,
31
- // layer: 'other',
32
- // },
33
- {
34
- test: /\.vue$/,
35
- loader: reach('./loader/fake-vue-loader.mjs'),
36
- options: {
37
- componentRoot: COMPONENT_ROOT,
38
- },
39
- },
40
- {
41
- test: /\.wxml$/,
42
- type: 'asset/resource',
43
- loader: reach('@into-mini/wxml-loader'),
44
- generator: {
45
- filename: '[entry][ext]',
46
- // filename: '[contenthash:8][ext]',
47
- },
48
- },
49
- {
50
- test: /\.hack$/,
51
- type: 'javascript/esm',
52
- layer: configKeys.hack,
53
- loader: reach('./loader/hack-entry-loader.mjs'),
54
- },
55
- );
56
- }
57
-
58
- #prepare(compiler) {
59
- compiler.options.resolve.extensionAlias ??= {};
60
-
61
- compiler.options.resolve.extensionAlias['.yaml'] = [
62
- '.yaml',
63
- '.yml',
64
- '.json',
65
- ];
66
-
67
- compiler.options.resolve.fallback ??= {};
68
-
69
- if (compiler.options.entry?.main) {
70
- delete compiler.options.entry.main;
71
- }
72
-
73
- Object.assign(compiler, {
74
- __entries__: new Map(),
75
- });
76
- }
77
-
78
- apply(compiler) {
79
- this.#prepare(compiler);
80
- this.#applyLoader(compiler);
81
-
82
- const { type, tagMatcher, preserveTap } = this;
83
-
84
- if (type) {
85
- new MinaRuntimeWebpackPlugin().apply(compiler);
86
- new AddEntryPlugin().apply(compiler);
87
- new AddWxsPlugin().apply(compiler);
88
- new SfcSplitPlugin({ tagMatcher, preserveTap }).apply(compiler);
89
- new ExposeEntryNamePlugin().apply(compiler);
90
- // new EntryRenamePlugin({ issuer: /\.vue$/, test: /\.wxml/ }).apply(
91
- // compiler,
92
- // );
93
- new FindEntryPlugin({ type }).apply(compiler);
94
- new CopyConfigPlugin({ type }).apply(compiler);
95
- }
96
-
97
- if (type === 'miniprogram') {
98
- new EmitFakePlugin().apply(compiler);
99
- }
100
- }
101
- }