@plumeria/webpack-plugin 3.0.1 → 4.0.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.
Files changed (2) hide show
  1. package/dist/index.js +276 -100
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -10,6 +10,9 @@ const path_1 = __importDefault(require("path"));
10
10
  const zss_engine_1 = require("zss-engine");
11
11
  const utils_1 = require("@plumeria/utils");
12
12
  const VIRTUAL_FILE_PATH = path_1.default.resolve(__dirname, '..', 'zero-virtual.css');
13
+ if (process.env.NODE_ENV === 'production') {
14
+ fs_1.default.writeFileSync(VIRTUAL_FILE_PATH, '/** Placeholder file */', 'utf-8');
15
+ }
13
16
  function loader(source) {
14
17
  const callback = this.async();
15
18
  if (this.resourcePath.includes('node_modules') ||
@@ -37,37 +40,108 @@ function loader(source) {
37
40
  });
38
41
  const localConsts = (0, utils_1.collectLocalConsts)(ast);
39
42
  Object.assign(utils_1.tables.staticTable, localConsts);
43
+ const isTSFile = this.resourcePath.endsWith('.ts') && !this.resourcePath.endsWith('.tsx');
40
44
  const localCreateStyles = {};
41
45
  const replacements = [];
42
- (0, utils_1.traverse)(ast, {
43
- VariableDeclarator({ node }) {
44
- if (node.id.type === 'Identifier' &&
45
- node.init &&
46
- utils_1.t.isCallExpression(node.init) &&
47
- utils_1.t.isMemberExpression(node.init.callee) &&
48
- utils_1.t.isIdentifier(node.init.callee.object, { name: 'css' }) &&
49
- utils_1.t.isIdentifier(node.init.callee.property, { name: 'create' }) &&
50
- node.init.arguments.length === 1 &&
46
+ const processedDecls = new Set();
47
+ const excludedSpans = new Set();
48
+ const idSpans = new Set();
49
+ const registerStyle = (node, declSpan, isExported) => {
50
+ if (utils_1.t.isIdentifier(node.id) &&
51
+ node.init &&
52
+ utils_1.t.isCallExpression(node.init) &&
53
+ utils_1.t.isMemberExpression(node.init.callee) &&
54
+ utils_1.t.isIdentifier(node.init.callee.object, { name: 'css' }) &&
55
+ utils_1.t.isIdentifier(node.init.callee.property) &&
56
+ node.init.arguments.length >= 1) {
57
+ const propName = node.init.callee.property.value;
58
+ if (propName === 'create' &&
51
59
  utils_1.t.isObjectExpression(node.init.arguments[0].expression)) {
52
60
  const obj = (0, utils_1.objectExpressionToObject)(node.init.arguments[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
53
61
  if (obj) {
54
- localCreateStyles[node.id.value] = obj;
55
62
  const hashMap = {};
56
63
  Object.entries(obj).forEach(([key, style]) => {
57
64
  const records = (0, utils_1.getStyleRecords)(key, style, 2);
58
- const propMap = {};
59
65
  (0, utils_1.extractOndemandStyles)(style, extractedSheets);
60
66
  records.forEach((r) => {
61
- propMap[r.key] = r.hash;
62
67
  extractedSheets.push(r.sheet);
63
68
  });
64
- hashMap[key] = records.map((r) => r.hash).join(' ');
69
+ const atomMap = {};
70
+ records.forEach((r) => (atomMap[r.key] = r.hash));
71
+ hashMap[key] = atomMap;
65
72
  });
66
- replacements.push({
73
+ if (utils_1.t.isIdentifier(node.id)) {
74
+ idSpans.add(node.id.span.start);
75
+ }
76
+ localCreateStyles[node.id.value] = {
77
+ name: node.id.value,
78
+ type: 'create',
79
+ obj,
80
+ hashMap,
81
+ hasDynamicAccess: false,
82
+ isExported,
83
+ initSpan: {
84
+ start: node.init.span.start - ast.span.start,
85
+ end: node.init.span.end - ast.span.start,
86
+ },
87
+ declSpan: {
88
+ start: declSpan.start - ast.span.start,
89
+ end: declSpan.end - ast.span.start,
90
+ },
91
+ };
92
+ }
93
+ }
94
+ else if ((propName === 'createTheme' || propName === 'createStatic') &&
95
+ (utils_1.t.isObjectExpression(node.init.arguments[0].expression) ||
96
+ utils_1.t.isStringLiteral(node.init.arguments[0].expression))) {
97
+ localCreateStyles[node.id.value] = {
98
+ name: node.id.value,
99
+ type: 'constant',
100
+ obj: {},
101
+ hashMap: {},
102
+ hasDynamicAccess: false,
103
+ isExported,
104
+ initSpan: {
67
105
  start: node.init.span.start - ast.span.start,
68
106
  end: node.init.span.end - ast.span.start,
69
- content: JSON.stringify(hashMap),
70
- });
107
+ },
108
+ declSpan: {
109
+ start: declSpan.start - ast.span.start,
110
+ end: declSpan.end - ast.span.start,
111
+ },
112
+ };
113
+ }
114
+ }
115
+ };
116
+ (0, utils_1.traverse)(ast, {
117
+ ExportDeclaration({ node }) {
118
+ if (utils_1.t.isVariableDeclaration(node.declaration)) {
119
+ processedDecls.add(node.declaration);
120
+ node.declaration.declarations.forEach((decl) => {
121
+ registerStyle(decl, node.span, true);
122
+ });
123
+ }
124
+ },
125
+ VariableDeclaration({ node }) {
126
+ if (processedDecls.has(node))
127
+ return;
128
+ node.declarations.forEach((decl) => {
129
+ registerStyle(decl, node.span, false);
130
+ });
131
+ },
132
+ MemberExpression({ node }) {
133
+ if (utils_1.t.isIdentifier(node.object)) {
134
+ const styleInfo = localCreateStyles[node.object.value];
135
+ if (styleInfo) {
136
+ if (utils_1.t.isIdentifier(node.property)) {
137
+ const hash = styleInfo.hashMap[node.property.value];
138
+ if (!hash && styleInfo.type !== 'constant') {
139
+ styleInfo.hasDynamicAccess = true;
140
+ }
141
+ }
142
+ else {
143
+ styleInfo.hasDynamicAccess = true;
144
+ }
71
145
  }
72
146
  }
73
147
  },
@@ -76,66 +150,9 @@ function loader(source) {
76
150
  if (utils_1.t.isMemberExpression(callee) &&
77
151
  utils_1.t.isIdentifier(callee.object, { name: 'css' }) &&
78
152
  utils_1.t.isIdentifier(callee.property)) {
153
+ const propName = callee.property.value;
79
154
  const args = node.arguments;
80
- if (callee.property.value === 'props') {
81
- const merged = {};
82
- let allStatic = true;
83
- args.forEach((arg) => {
84
- const expr = arg.expression;
85
- if (utils_1.t.isObjectExpression(expr)) {
86
- const obj = (0, utils_1.objectExpressionToObject)(expr, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
87
- if (obj) {
88
- Object.assign(merged, obj);
89
- }
90
- else {
91
- allStatic = false;
92
- }
93
- }
94
- else if (utils_1.t.isMemberExpression(expr)) {
95
- if (utils_1.t.isIdentifier(expr.object) &&
96
- utils_1.t.isIdentifier(expr.property)) {
97
- const varName = expr.object.value;
98
- const propName = expr.property.value;
99
- const styleSet = localCreateStyles[varName];
100
- if (styleSet && styleSet[propName]) {
101
- Object.assign(merged, styleSet[propName]);
102
- }
103
- else {
104
- allStatic = false;
105
- }
106
- }
107
- else {
108
- allStatic = false;
109
- }
110
- }
111
- else if (utils_1.t.isIdentifier(expr)) {
112
- const obj = localCreateStyles[expr.value];
113
- if (obj) {
114
- Object.assign(merged, obj);
115
- }
116
- else {
117
- allStatic = false;
118
- }
119
- }
120
- else {
121
- allStatic = false;
122
- }
123
- });
124
- if (allStatic && Object.keys(merged).length > 0) {
125
- (0, utils_1.extractOndemandStyles)(merged, extractedSheets);
126
- const hash = (0, zss_engine_1.genBase36Hash)(merged, 1, 8);
127
- const records = (0, utils_1.getStyleRecords)(hash, merged, 2);
128
- records.forEach((r) => {
129
- extractedSheets.push(r.sheet);
130
- });
131
- replacements.push({
132
- start: node.span.start - ast.span.start,
133
- end: node.span.end - ast.span.start,
134
- content: JSON.stringify(records.map((r) => r.hash).join(' ')),
135
- });
136
- }
137
- }
138
- else if (callee.property.value === 'keyframes' &&
155
+ if (propName === 'keyframes' &&
139
156
  args.length > 0 &&
140
157
  utils_1.t.isObjectExpression(args[0].expression)) {
141
158
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
@@ -147,42 +164,208 @@ function loader(source) {
147
164
  content: JSON.stringify(`kf-${hash}`),
148
165
  });
149
166
  }
150
- else if (callee.property.value === 'viewTransition' &&
167
+ else if (propName === 'viewTransition' &&
151
168
  args.length > 0 &&
152
169
  utils_1.t.isObjectExpression(args[0].expression)) {
153
170
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
154
171
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
155
172
  utils_1.tables.viewTransitionObjectTable[hash] = obj;
173
+ (0, utils_1.extractOndemandStyles)(obj, extractedSheets);
174
+ (0, utils_1.extractOndemandStyles)({ vt: `vt-${hash}` }, extractedSheets);
156
175
  replacements.push({
157
176
  start: node.span.start - ast.span.start,
158
177
  end: node.span.end - ast.span.start,
159
178
  content: JSON.stringify(`vt-${hash}`),
160
179
  });
161
180
  }
162
- else if (callee.property.value === 'createTheme' &&
181
+ else if (propName === 'createTheme' &&
163
182
  args.length > 0 &&
164
183
  utils_1.t.isObjectExpression(args[0].expression)) {
165
184
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
166
185
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
167
186
  utils_1.tables.createThemeObjectTable[hash] = obj;
168
- replacements.push({
169
- start: node.span.start - ast.span.start,
170
- end: node.span.end - ast.span.start,
171
- content: JSON.stringify(''),
172
- });
173
187
  }
174
- else if (callee.property.value === 'createStatic' &&
175
- args.length > 0 &&
176
- utils_1.t.isStringLiteral(args[0].expression)) {
177
- replacements.push({
178
- start: node.span.start - ast.span.start,
179
- end: node.span.end - ast.span.start,
180
- content: JSON.stringify(''),
188
+ }
189
+ },
190
+ });
191
+ (0, utils_1.traverse)(ast, {
192
+ MemberExpression({ node }) {
193
+ if (excludedSpans.has(node.span.start))
194
+ return;
195
+ if (utils_1.t.isIdentifier(node.object) && utils_1.t.isIdentifier(node.property)) {
196
+ const styleInfo = localCreateStyles[node.object.value];
197
+ if (styleInfo && !styleInfo.hasDynamicAccess) {
198
+ const atomMap = styleInfo.hashMap[node.property.value];
199
+ if (atomMap) {
200
+ const combinedHash = Object.values(atomMap).join(' ');
201
+ replacements.push({
202
+ start: node.span.start - ast.span.start,
203
+ end: node.span.end - ast.span.start,
204
+ content: JSON.stringify(combinedHash),
205
+ });
206
+ }
207
+ }
208
+ }
209
+ },
210
+ Identifier({ node }) {
211
+ if (excludedSpans.has(node.span.start))
212
+ return;
213
+ if (idSpans.has(node.span.start))
214
+ return;
215
+ const styleInfo = localCreateStyles[node.value];
216
+ if (styleInfo && !styleInfo.hasDynamicAccess) {
217
+ const fullHashMap = {};
218
+ Object.entries(styleInfo.hashMap).forEach(([key, atomMap]) => {
219
+ fullHashMap[key] = Object.values(atomMap).join(' ');
220
+ });
221
+ replacements.push({
222
+ start: node.span.start - ast.span.start,
223
+ end: node.span.end - ast.span.start,
224
+ content: JSON.stringify(fullHashMap),
225
+ });
226
+ }
227
+ },
228
+ CallExpression({ node }) {
229
+ const callee = node.callee;
230
+ if (utils_1.t.isMemberExpression(callee) &&
231
+ utils_1.t.isIdentifier(callee.object, { name: 'css' }) &&
232
+ utils_1.t.isIdentifier(callee.property, { name: 'props' })) {
233
+ const args = node.arguments;
234
+ const checkStatic = (expr) => {
235
+ if (utils_1.t.isObjectExpression(expr) ||
236
+ utils_1.t.isStringLiteral(expr) ||
237
+ utils_1.t.isNumericLiteral(expr) ||
238
+ utils_1.t.isBooleanLiteral(expr) ||
239
+ utils_1.t.isNullLiteral(expr))
240
+ return true;
241
+ if (utils_1.t.isMemberExpression(expr) &&
242
+ utils_1.t.isIdentifier(expr.object) &&
243
+ utils_1.t.isIdentifier(expr.property)) {
244
+ const styleInfo = localCreateStyles[expr.object.value];
245
+ return !!(styleInfo &&
246
+ !styleInfo.hasDynamicAccess &&
247
+ styleInfo.hashMap[expr.property.value]);
248
+ }
249
+ if (utils_1.t.isIdentifier(expr)) {
250
+ const styleInfo = localCreateStyles[expr.value];
251
+ return !!(styleInfo && !styleInfo.hasDynamicAccess);
252
+ }
253
+ return false;
254
+ };
255
+ const allStatic = args.every((arg) => checkStatic(arg.expression));
256
+ if (allStatic) {
257
+ const merged = {};
258
+ args.forEach((arg) => {
259
+ const expr = arg.expression;
260
+ if (utils_1.t.isObjectExpression(expr)) {
261
+ const obj = (0, utils_1.objectExpressionToObject)(expr, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
262
+ obj && Object.assign(merged, obj);
263
+ }
264
+ else if (utils_1.t.isMemberExpression(expr) &&
265
+ utils_1.t.isIdentifier(expr.object) &&
266
+ utils_1.t.isIdentifier(expr.property)) {
267
+ const styleInfo = localCreateStyles[expr.object.value];
268
+ if (styleInfo) {
269
+ Object.assign(merged, styleInfo.obj[expr.property.value]);
270
+ }
271
+ }
272
+ else if (utils_1.t.isIdentifier(expr)) {
273
+ const styleInfo = localCreateStyles[expr.value];
274
+ if (styleInfo) {
275
+ Object.assign(merged, styleInfo.obj);
276
+ }
277
+ }
181
278
  });
279
+ if (Object.keys(merged).length > 0) {
280
+ (0, utils_1.extractOndemandStyles)(merged, extractedSheets);
281
+ const hash = (0, zss_engine_1.genBase36Hash)(merged, 1, 8);
282
+ const records = (0, utils_1.getStyleRecords)(hash, merged, 2);
283
+ records.forEach((r) => extractedSheets.push(r.sheet));
284
+ const resultHash = records
285
+ .map((r) => r.hash)
286
+ .join(' ');
287
+ replacements.push({
288
+ start: node.span.start - ast.span.start,
289
+ end: node.span.end - ast.span.start,
290
+ content: JSON.stringify(resultHash),
291
+ });
292
+ }
293
+ }
294
+ else {
295
+ const processExpr = (expr) => {
296
+ if (utils_1.t.isMemberExpression(expr) &&
297
+ utils_1.t.isIdentifier(expr.object) &&
298
+ utils_1.t.isIdentifier(expr.property)) {
299
+ const info = localCreateStyles[expr.object.value];
300
+ if (info) {
301
+ const atomMap = info.hashMap[expr.property.value];
302
+ if (atomMap) {
303
+ excludedSpans.add(expr.span.start);
304
+ replacements.push({
305
+ start: expr.span.start - ast.span.start,
306
+ end: expr.span.end - ast.span.start,
307
+ content: JSON.stringify(atomMap),
308
+ });
309
+ }
310
+ }
311
+ }
312
+ else if (utils_1.t.isIdentifier(expr)) {
313
+ const info = localCreateStyles[expr.value];
314
+ if (info) {
315
+ info.hasDynamicAccess = true;
316
+ excludedSpans.add(expr.span.start);
317
+ replacements.push({
318
+ start: expr.span.start - ast.span.start,
319
+ end: expr.span.end - ast.span.start,
320
+ content: JSON.stringify(info.hashMap),
321
+ });
322
+ }
323
+ }
324
+ else if (utils_1.t.isConditionalExpression(expr)) {
325
+ processExpr(expr.consequent);
326
+ processExpr(expr.alternate);
327
+ }
328
+ else if (utils_1.t.isBinaryExpression(expr) &&
329
+ (expr.operator === '&&' ||
330
+ expr.operator === '||' ||
331
+ expr.operator === '??')) {
332
+ processExpr(expr.left);
333
+ processExpr(expr.right);
334
+ }
335
+ };
336
+ args.forEach((arg) => processExpr(arg.expression));
182
337
  }
183
338
  }
184
339
  },
185
340
  });
341
+ Object.values(localCreateStyles).forEach((info) => {
342
+ if (info.isExported) {
343
+ const content = isTSFile || info.hasDynamicAccess
344
+ ? JSON.stringify(info.hashMap)
345
+ : JSON.stringify('');
346
+ replacements.push({
347
+ start: info.initSpan.start,
348
+ end: info.initSpan.end,
349
+ content,
350
+ });
351
+ }
352
+ else {
353
+ if (info.hasDynamicAccess) {
354
+ replacements.push({
355
+ start: info.initSpan.start,
356
+ end: info.initSpan.end,
357
+ content: JSON.stringify(info.hashMap),
358
+ });
359
+ }
360
+ else {
361
+ replacements.push({
362
+ start: info.declSpan.start,
363
+ end: info.declSpan.end,
364
+ content: '',
365
+ });
366
+ }
367
+ }
368
+ });
186
369
  if (extractedSheets.length > 0) {
187
370
  fileStyles.baseStyles =
188
371
  (fileStyles.baseStyles || '') + extractedSheets.join('');
@@ -191,8 +374,10 @@ function loader(source) {
191
374
  let offset = 0;
192
375
  const parts = [];
193
376
  replacements
194
- .sort((a, b) => a.start - b.start)
377
+ .sort((a, b) => a.start - b.start || b.end - a.end)
195
378
  .forEach((r) => {
379
+ if (r.start < offset)
380
+ return;
196
381
  parts.push(buffer.subarray(offset, r.start));
197
382
  parts.push(Buffer.from(r.content));
198
383
  offset = r.end;
@@ -210,12 +395,7 @@ function loader(source) {
210
395
  }
211
396
  const virtualCssRequest = stringifyRequest(this, `${VIRTUAL_CSS_PATH}`);
212
397
  const postfix = `\nimport ${virtualCssRequest};`;
213
- let css = '';
214
- try {
215
- css = fs_1.default.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
216
- }
217
- catch (e) {
218
- }
398
+ const css = fs_1.default.readFileSync(VIRTUAL_FILE_PATH, 'utf-8');
219
399
  function generateOrderedCSS(styles) {
220
400
  const sections = [];
221
401
  if (styles.keyframeStyles?.trim()) {
@@ -271,10 +451,6 @@ function loader(source) {
271
451
  if (extractedSheets.length > 0 && process.env.NODE_ENV === 'development') {
272
452
  fs_1.default.appendFileSync(VIRTUAL_FILE_PATH, extractedSheets.join(''), 'utf-8');
273
453
  }
274
- else if (extractedSheets.length > 0 &&
275
- process.env.NODE_ENV === 'production') {
276
- fs_1.default.writeFileSync(VIRTUAL_FILE_PATH, '');
277
- }
278
454
  const useClientDirective = /^\s*['"]use client['"]/;
279
455
  if (process.env.NODE_ENV === 'production')
280
456
  return callback(null, transformedSource);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/webpack-plugin",
3
- "version": "3.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Plumeria Webpack plugin",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "zero-virtual.css"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/utils": "^3.0.1"
25
+ "@plumeria/utils": "^4.0.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@swc/core": "1.15.2",