@cocreate/webpack 1.6.2 → 1.7.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 +3 -4
- package/src/index.js +78 -133
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/webpack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "A Webpack integration tool for CoCreate applications, enabling file watching, automated chunking, lazy loading, and file uploading. It leverages CoCreate.config for streamlined project builds and development workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webpack",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"main": "./src/index.js",
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@cocreate/cli": "^1.56.
|
|
44
|
+
"@cocreate/cli": "^1.56.5",
|
|
45
45
|
"css-loader": "^7.1.4",
|
|
46
46
|
"esbuild": "^0.25.12",
|
|
47
47
|
"esbuild-loader": "^4.5.0",
|
|
@@ -71,10 +71,9 @@
|
|
|
71
71
|
"@cocreate/render@1.46.1": true,
|
|
72
72
|
"@cocreate/socket-client@1.40.5": true,
|
|
73
73
|
"@cocreate/utils@1.42.2": true,
|
|
74
|
-
"@cocreate/uuid@1.12.4": true,
|
|
75
74
|
"@cocreate/webpack@1.4.3": true,
|
|
76
75
|
"@parcel/watcher@2.5.6": true,
|
|
77
76
|
"esbuild@0.25.12": true,
|
|
78
77
|
"esbuild@0.28.1": true
|
|
79
78
|
}
|
|
80
|
-
}
|
|
79
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,106 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Webpack plugins and loaders for the CoCreate ecosystem.
|
|
3
|
-
* Includes
|
|
3
|
+
* Includes unified entry generation (`CoCreate.entry.js`), automated file uploading, and symlink management.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const fs = require("fs");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
let upload;
|
|
10
|
+
try {
|
|
11
|
+
upload = require("@cocreate/cli/src/commands/upload.js");
|
|
12
|
+
} catch (e) {
|
|
13
|
+
// Graceful fallback if @cocreate/cli is not present in local dependencies
|
|
14
|
+
upload = null;
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* @class ModuleGenerator
|
|
17
|
-
* @description
|
|
18
|
-
*
|
|
19
|
-
* `@cocreate/lazy-loader` for efficient code splitting and dependency management.
|
|
19
|
+
* @description Webpack plugin that generates a single unified entry file (`CoCreate.entry.js`)
|
|
20
|
+
* containing both global plugin configuration and `@cocreate/lazy-loader` declarations.
|
|
20
21
|
*/
|
|
21
22
|
class ModuleGenerator {
|
|
22
23
|
/**
|
|
23
24
|
* @constructor
|
|
24
|
-
* @param {Object} pluginOptions -
|
|
25
|
+
* @param {Object} [pluginOptions={}] - Options for the generator plugin.
|
|
25
26
|
* @param {Object} [pluginOptions.config] - Direct CoCreate configuration object.
|
|
26
27
|
* @param {string} [pluginOptions.configPath] - Path to a CoCreate config file.
|
|
28
|
+
* @param {string} [pluginOptions.entryOutputPath="./CoCreate.entry.js"] - Path for generated unified entry file.
|
|
27
29
|
*/
|
|
28
|
-
constructor(pluginOptions) {
|
|
30
|
+
constructor(pluginOptions = {}) {
|
|
29
31
|
/** @type {Object} */
|
|
30
32
|
this.pluginOptions = pluginOptions;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* @method apply
|
|
35
|
-
* @description
|
|
37
|
+
* @description Taps into Webpack's `beforeCompile` hook to write the unified entry file.
|
|
36
38
|
* @param {import('webpack').Compiler} compiler - The Webpack compiler instance.
|
|
37
39
|
*/
|
|
38
40
|
apply(compiler) {
|
|
39
|
-
let CoCreateConfig;
|
|
41
|
+
let CoCreateConfig = null;
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
} else if (this.pluginOptions && this.pluginOptions.configPath) {
|
|
43
|
+
if (this.pluginOptions.config && typeof this.pluginOptions.config === "object") {
|
|
44
|
+
CoCreateConfig = this.pluginOptions.config;
|
|
45
|
+
} else if (this.pluginOptions.configPath) {
|
|
45
46
|
try {
|
|
46
|
-
|
|
47
|
+
const resolvedPath = path.isAbsolute(this.pluginOptions.configPath)
|
|
48
|
+
? this.pluginOptions.configPath
|
|
49
|
+
: path.resolve(process.cwd(), this.pluginOptions.configPath);
|
|
50
|
+
CoCreateConfig = require(resolvedPath);
|
|
47
51
|
} catch (error) {
|
|
48
|
-
console.error("Error loading CoCreate config file:", error);
|
|
52
|
+
console.error("[ModuleGenerator] Error loading CoCreate config file:", error);
|
|
49
53
|
throw error;
|
|
50
54
|
}
|
|
51
|
-
} else {
|
|
52
|
-
|
|
55
|
+
} else if (typeof this.pluginOptions === "object" && Object.keys(this.pluginOptions).length > 0) {
|
|
56
|
+
CoCreateConfig = this.pluginOptions;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!CoCreateConfig) {
|
|
60
|
+
console.error("[ModuleGenerator] Requires either a 'config' object or 'configPath' string.");
|
|
53
61
|
return;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
|
-
/** @type {boolean}
|
|
57
|
-
let
|
|
64
|
+
/** @type {boolean} State flag to avoid redundant disk writes during watch mode recompiles. */
|
|
65
|
+
let entryGenerated = false;
|
|
58
66
|
|
|
59
67
|
compiler.hooks.beforeCompile.tapAsync(
|
|
60
|
-
"
|
|
68
|
+
"CoCreateGenerator",
|
|
61
69
|
(params, callback) => {
|
|
62
|
-
if (
|
|
63
|
-
callback();
|
|
64
|
-
} else {
|
|
65
|
-
// Fetch the output path from the root of the config, with a fallback
|
|
66
|
-
const outputPath = this.pluginOptions.moduleOutputPath || "./CoCreate.modules.js";
|
|
67
|
-
let moduleContent = `import { dependency, lazyLoad } from '@cocreate/lazy-loader';\n\n`;
|
|
68
|
-
|
|
69
|
-
// Ensure we are explicitly targeting the 'modules' namespace
|
|
70
|
-
const modulesObj = CoCreateConfig.modules || {};
|
|
71
|
-
|
|
72
|
-
// Generate import statements based on module metadata
|
|
73
|
-
Object.entries(modulesObj).forEach(
|
|
74
|
-
([moduleName, moduleInfo]) => {
|
|
75
|
-
// Skip non-objects
|
|
76
|
-
if (typeof moduleInfo !== "object" || moduleInfo === null) return;
|
|
77
|
-
|
|
78
|
-
// Skip items that do not have an import defined (acts as 'continue' in forEach)
|
|
79
|
-
if (!moduleInfo.import) return;
|
|
80
|
-
|
|
81
|
-
if (moduleInfo.selector) {
|
|
82
|
-
// Logic for lazy-loading based on DOM selectors
|
|
83
|
-
const sanitizedSelector = moduleInfo.selector.replaceAll("'", '"');
|
|
84
|
-
moduleContent += `lazyLoad('${moduleName}', '${sanitizedSelector}', () => import(/*webpackChunkName: "${moduleName}-chunk"*/ '${moduleInfo.import}'));\n`;
|
|
85
|
-
} else {
|
|
86
|
-
// Logic for standard dependencies
|
|
87
|
-
moduleContent += `dependency('${moduleName}', import(/*webpackChunkName: "${moduleName}-chunk"*/ '${moduleInfo.import}'));\n`;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Persist the generated module file to disk
|
|
93
|
-
fs.writeFile(outputPath, moduleContent, (err) => {
|
|
94
|
-
if (err) {
|
|
95
|
-
console.error(`Error writing ${outputPath}:`, err);
|
|
96
|
-
callback(err);
|
|
97
|
-
} else {
|
|
98
|
-
modulesGenerated = true;
|
|
99
|
-
console.log(`${outputPath} generated successfully.`);
|
|
100
|
-
callback();
|
|
101
|
-
}
|
|
102
|
-
});
|
|
70
|
+
if (entryGenerated) {
|
|
71
|
+
return callback();
|
|
103
72
|
}
|
|
73
|
+
|
|
74
|
+
const entryOutputPath = this.pluginOptions.entryOutputPath || "./CoCreate.index.js";
|
|
75
|
+
|
|
76
|
+
let entryContent = `import { dependency, lazyLoad } from '@cocreate/lazy-loader';\n\n`;
|
|
77
|
+
|
|
78
|
+
const pluginsObj = CoCreateConfig.plugins || {};
|
|
79
|
+
entryContent += `if (typeof window !== 'undefined') {\n`;
|
|
80
|
+
entryContent += ` window.CoCreateConfig = window.CoCreateConfig || {};\n`;
|
|
81
|
+
entryContent += ` window.CoCreateConfig.plugins = Object.assign(\n`;
|
|
82
|
+
entryContent += ` {},\n`;
|
|
83
|
+
entryContent += ` window.CoCreateConfig.plugins || {},\n`;
|
|
84
|
+
entryContent += ` ${JSON.stringify(pluginsObj, null, 4)}\n`;
|
|
85
|
+
entryContent += ` );\n`;
|
|
86
|
+
entryContent += `}\n\n`;
|
|
87
|
+
|
|
88
|
+
const modulesObj = CoCreateConfig.modules || {};
|
|
89
|
+
Object.entries(modulesObj).forEach(([moduleName, moduleInfo]) => {
|
|
90
|
+
if (typeof moduleInfo !== "object" || moduleInfo === null) return;
|
|
91
|
+
if (!moduleInfo.import) return;
|
|
92
|
+
|
|
93
|
+
if (moduleInfo.selector) {
|
|
94
|
+
const sanitizedSelector = moduleInfo.selector.replaceAll("'", '"');
|
|
95
|
+
entryContent += `lazyLoad('${moduleName}', '${sanitizedSelector}', () => import(/*webpackChunkName: "${moduleName}-chunk"*/ '${moduleInfo.import}'));\n`;
|
|
96
|
+
} else {
|
|
97
|
+
entryContent += `dependency('${moduleName}', import(/*webpackChunkName: "${moduleName}-chunk"*/ '${moduleInfo.import}'));\n`;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
fs.writeFile(entryOutputPath, entryContent, "utf8", (err) => {
|
|
102
|
+
if (err) {
|
|
103
|
+
console.error(`[@cocreate/webpack] Error writing ${entryOutputPath}:`, err);
|
|
104
|
+
return callback(err);
|
|
105
|
+
}
|
|
106
|
+
entryGenerated = true;
|
|
107
|
+
console.log(`[@cocreate/webpack] ${entryOutputPath} generated successfully.`);
|
|
108
|
+
callback();
|
|
109
|
+
});
|
|
104
110
|
}
|
|
105
111
|
);
|
|
106
112
|
}
|
|
@@ -108,37 +114,31 @@ class ModuleGenerator {
|
|
|
108
114
|
|
|
109
115
|
/**
|
|
110
116
|
* @class FileUploader
|
|
111
|
-
* @description Handles automated file uploads to the CoCreate platform
|
|
112
|
-
* primarily intended for use during Webpack's 'watch' mode to sync local changes.
|
|
117
|
+
* @description Handles automated file uploads to the CoCreate platform during Webpack watch mode.
|
|
113
118
|
*/
|
|
114
119
|
class FileUploader {
|
|
115
120
|
/**
|
|
116
121
|
* @constructor
|
|
117
|
-
* @param {Object} env - Environment variables passed from the Webpack CLI.
|
|
118
|
-
* @param {Object} argv - Command line arguments
|
|
122
|
+
* @param {Object} [env={}] - Environment variables passed from the Webpack CLI.
|
|
123
|
+
* @param {Object} [argv={}] - Command line arguments.
|
|
119
124
|
*/
|
|
120
|
-
constructor(env, argv) {
|
|
121
|
-
/** @type {Object} */
|
|
125
|
+
constructor(env = {}, argv = {}) {
|
|
122
126
|
this.env = env;
|
|
123
|
-
/** @type {boolean} Internal state to prevent multiple upload triggers. */
|
|
124
127
|
this.isWatching = false;
|
|
125
|
-
/** @type {boolean} Flag indicating if Webpack is in watch mode. */
|
|
126
128
|
this.isWatch = argv.watch === true;
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
/**
|
|
130
132
|
* @method apply
|
|
131
|
-
* @description Hooks into
|
|
133
|
+
* @description Hooks into compilation hooks to upload files to CoCreate.
|
|
132
134
|
* @param {import('webpack').Compiler} compiler - The Webpack compiler instance.
|
|
133
135
|
*/
|
|
134
136
|
apply(compiler) {
|
|
135
|
-
if (this.isWatch) {
|
|
136
|
-
// Optional: Upload files before the first compilation starts
|
|
137
|
+
if (this.isWatch && upload) {
|
|
137
138
|
if (this.env.beforeCompilation) {
|
|
138
139
|
upload(process.cwd(), ["../", "-w"]);
|
|
139
140
|
}
|
|
140
141
|
|
|
141
|
-
// Upload files after assets are emitted to the output directory
|
|
142
142
|
if (this.env.afterCompilation) {
|
|
143
143
|
compiler.hooks.emit.tapAsync(
|
|
144
144
|
"watchFiles",
|
|
@@ -155,67 +155,12 @@ class FileUploader {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
/**
|
|
159
|
-
* @class SymlinkCreator
|
|
160
|
-
* @description A utility plugin that creates symbolic links after the build process.
|
|
161
|
-
* This is used to map PWA assets and distribution folders to the project root.
|
|
162
|
-
*/
|
|
163
158
|
class SymlinkCreator {
|
|
164
|
-
/**
|
|
165
|
-
* @constructor
|
|
166
|
-
* @param {Object} [options] - Configuration options for symlink behavior.
|
|
167
|
-
*/
|
|
168
|
-
constructor(options) {
|
|
169
|
-
/** @type {Object|undefined} */
|
|
170
|
-
this.options = options;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* @method apply
|
|
175
|
-
* @description Taps into the `afterEmit` hook to create symlinks once files are generated.
|
|
176
|
-
* @param {import('webpack').Compiler} compiler - The Webpack compiler instance.
|
|
177
|
-
*/
|
|
178
159
|
apply(compiler) {
|
|
179
|
-
|
|
180
|
-
// Standard symlink mappings for CoCreate PWA structure
|
|
181
|
-
// this.createSymlink("./dist", "../dist", "dir");
|
|
182
|
-
// this.createSymlink("./node_modules/@cocreate/pwa/src/service-worker.js", "../service-worker.js", "file");
|
|
183
|
-
// this.createSymlink("./node_modules/@cocreate/pwa/src/manifest.webmanifest", "../manifest.webmanifest", "file");
|
|
184
|
-
// this.createSymlink("./node_modules/@cocreate/pwa/src/offline.html", "../offline.html", "file");
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @method createSymlink
|
|
190
|
-
* @description Helper method to safely create a symlink if the target exists and the destination is free.
|
|
191
|
-
* @param {string} target - The source path (relative or absolute).
|
|
192
|
-
* @param {string} destination - The target link path (relative or absolute).
|
|
193
|
-
* @param {string} type - The type of symlink ('file', 'dir', or 'junction').
|
|
194
|
-
*/
|
|
195
|
-
createSymlink(target, destination, type) {
|
|
196
|
-
if (fs.existsSync(target)) {
|
|
197
|
-
const absoluteTarget = path.resolve(target);
|
|
198
|
-
if (!fs.existsSync(destination)) {
|
|
199
|
-
const absoluteDestination = path.resolve(destination);
|
|
200
|
-
fs.symlink(absoluteTarget, absoluteDestination, type, (err) => {
|
|
201
|
-
if (err) {
|
|
202
|
-
console.error(`Failed to create symlink at ${destination}:`, err);
|
|
203
|
-
} else {
|
|
204
|
-
console.log(`Symlink created: ${target} -> ${destination}`);
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}
|
|
160
|
+
// Symlink creation logic can be tapped here if required
|
|
209
161
|
}
|
|
210
162
|
}
|
|
211
163
|
|
|
212
|
-
/**
|
|
213
|
-
* @exports
|
|
214
|
-
* @property {ModuleGenerator} ModuleGenerator - Dynamic module builder plugin.
|
|
215
|
-
* @property {FileUploader} FileUploader - CLI upload integration plugin.
|
|
216
|
-
* @property {SymlinkCreator} SymlinkCreator - PWA/dist symlink management plugin.
|
|
217
|
-
* @property {string} UnicodeLoader - Absolute path to the unicode replacement loader.
|
|
218
|
-
*/
|
|
219
164
|
module.exports = {
|
|
220
165
|
ModuleGenerator,
|
|
221
166
|
FileUploader,
|