@alexgyver/component 1.5.0 → 2.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.
- package/Component.min.js +1 -1
- package/Component.min.js.gz +0 -0
- package/Component.pico.min.js +1 -0
- package/Component.pico.min.js.gz +0 -0
- package/Component.tiny.min.js +1 -0
- package/Component.tiny.min.js.gz +0 -0
- package/README.md +651 -259
- package/package.json +16 -9
- package/src/Component.js +15 -0
- package/src/EL.js +371 -0
- package/src/SVG.js +18 -0
- package/src/Sheet.js +73 -0
- package/src/State.js +47 -0
- package/src/utils.js +94 -0
- package/test/index.html +12 -0
- package/test/script.js +434 -148
- package/webpack.config.js +29 -10
- package/webpack.dev.config.js +32 -0
- package/Component.js +0 -388
- package/test/example.html +0 -15
package/test/script.js
CHANGED
|
@@ -1,148 +1,434 @@
|
|
|
1
|
-
|
|
2
|
-
import { EL,
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
'
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
});
|
|
1
|
+
import { addCSS, EL, useState, SVG, State } from "https://gyverlibs.github.io/Component.js/Component.min.js";
|
|
2
|
+
// import { addCSS, EL, useState, SVG, State } from "../src/Component.js";
|
|
3
|
+
|
|
4
|
+
// добавить стили в head
|
|
5
|
+
addCSS(`
|
|
6
|
+
body { font-family: sans-serif; padding: 20px; }
|
|
7
|
+
span { padding: 0 5px }
|
|
8
|
+
.card { border: 1px solid #ccc; padding: 10px; margin: 10px 0; border-radius: 6px; max-width: 250px; }
|
|
9
|
+
.btn { padding: 5px 10px; background: #007bff; color: white; border: none; cursor: pointer; border-radius: 4px; margin: 0 5px; }
|
|
10
|
+
.bordered { border: 1px solid red; }
|
|
11
|
+
hr { margin: 10px; }
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
test1();
|
|
15
|
+
test2();
|
|
16
|
+
test3();
|
|
17
|
+
test4();
|
|
18
|
+
test5();
|
|
19
|
+
test6();
|
|
20
|
+
test7();
|
|
21
|
+
test8();
|
|
22
|
+
test9();
|
|
23
|
+
test10();
|
|
24
|
+
|
|
25
|
+
// минимальный пример, настройка стилей
|
|
26
|
+
function test1() {
|
|
27
|
+
let div1 = EL.make('div', { // создать div
|
|
28
|
+
parent: document.body, // прикрепить к body
|
|
29
|
+
text: 'hello 1', // вывести текст
|
|
30
|
+
class: 'card bordered', // класс строкой
|
|
31
|
+
style: 'color: red', // стиль строкой
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// стили и классы можно задавать объектом
|
|
35
|
+
|
|
36
|
+
let div2 = EL.make('div', { // создать div
|
|
37
|
+
text: 'hello 2', // вывести текст
|
|
38
|
+
class: { // класс объектом + условно
|
|
39
|
+
card: true,
|
|
40
|
+
bordered: false,
|
|
41
|
+
},
|
|
42
|
+
style: { // стиль объектом
|
|
43
|
+
color: 'green',
|
|
44
|
+
'font-size': '20px',
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// можно прикрепить вручную
|
|
49
|
+
div2.mount(document.body);
|
|
50
|
+
// EL.mount(div2, document.body);
|
|
51
|
+
|
|
52
|
+
// через 1 сек поменять текст, стиль и убрать класс bordered
|
|
53
|
+
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
div1.update({
|
|
56
|
+
text: 'hello world!',
|
|
57
|
+
class: {
|
|
58
|
+
bordered: false,
|
|
59
|
+
},
|
|
60
|
+
style: {
|
|
61
|
+
color: 'unset',
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}, 1000);
|
|
65
|
+
|
|
66
|
+
// можно очистить/перезаписать стили и классы через _r
|
|
67
|
+
|
|
68
|
+
setTimeout(() => {
|
|
69
|
+
div2.update({
|
|
70
|
+
class_r: '',
|
|
71
|
+
style_r: '',
|
|
72
|
+
});
|
|
73
|
+
}, 2000);
|
|
74
|
+
|
|
75
|
+
EL.make('hr', { parent: document.body });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// вложенные элементы
|
|
79
|
+
function test2() {
|
|
80
|
+
EL.make('div', {
|
|
81
|
+
parent: document.body,
|
|
82
|
+
class: 'card',
|
|
83
|
+
child: [ // может быть массивом
|
|
84
|
+
{
|
|
85
|
+
tag: 'span',
|
|
86
|
+
text: 'hello 1',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
// без указания тега будет div
|
|
90
|
+
class: 'card',
|
|
91
|
+
child: { // может быть объектом (1 элемент)
|
|
92
|
+
tag: 'span',
|
|
93
|
+
text: 'hello 2',
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// трюки
|
|
100
|
+
|
|
101
|
+
EL.make('div', {
|
|
102
|
+
parent: document.body,
|
|
103
|
+
class: 'card',
|
|
104
|
+
child: [
|
|
105
|
+
{}, // валидно, пустой div
|
|
106
|
+
null, // валидно, ничего не добавится
|
|
107
|
+
undefined, // валидно, ничего не добавится
|
|
108
|
+
true && { // можно добавлять детей по условию
|
|
109
|
+
tag: 'span',
|
|
110
|
+
text: 'hello 1',
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
EL.make('hr', { parent: document.body });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// события и обработчики
|
|
119
|
+
function test3() {
|
|
120
|
+
EL.make('button', {
|
|
121
|
+
parent: document.body,
|
|
122
|
+
text: 'press me',
|
|
123
|
+
class: 'btn',
|
|
124
|
+
|
|
125
|
+
// обработчик клика
|
|
126
|
+
onclick: (e) => {
|
|
127
|
+
console.log('click!', e, e.el, e.ctx);
|
|
128
|
+
// e - Event
|
|
129
|
+
// e.el - сам элемент (кнопка)
|
|
130
|
+
// e.ctx - контекст (о нём ниже)
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// можно добавлять options для событий, обработчик указывается в handler
|
|
134
|
+
onmousedown: {
|
|
135
|
+
handler: () => console.log('press'),
|
|
136
|
+
once: true
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
// можно подключить ещё вот так
|
|
140
|
+
events: {
|
|
141
|
+
mousemove: () => { },
|
|
142
|
+
|
|
143
|
+
input: {
|
|
144
|
+
handler: () => { },
|
|
145
|
+
passive: false
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
EL.make('hr', { parent: document.body });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// жизненный цикл и его обработчики
|
|
154
|
+
function test4() {
|
|
155
|
+
// кнопка меняет счётчик, после 5 кликов кнопка удаляется
|
|
156
|
+
|
|
157
|
+
let count = 0;
|
|
158
|
+
|
|
159
|
+
EL.make('button', {
|
|
160
|
+
parent: document.body,
|
|
161
|
+
class: 'btn',
|
|
162
|
+
text: 'press',
|
|
163
|
+
onclick: e => {
|
|
164
|
+
e.el.update({ text: 'update ' + count });
|
|
165
|
+
if (++count == 5) e.el.remove();
|
|
166
|
+
},
|
|
167
|
+
also: () => {
|
|
168
|
+
console.log('div also'); // вызовется после make
|
|
169
|
+
},
|
|
170
|
+
onMount: () => {
|
|
171
|
+
console.log('div mount'); // вызовется после добавления в body
|
|
172
|
+
},
|
|
173
|
+
onRender: () => {
|
|
174
|
+
console.log('div render'); // вызовется после фактического рендера
|
|
175
|
+
},
|
|
176
|
+
onUpdate: () => {
|
|
177
|
+
console.log('div update'); // вызовется после обновления параметров
|
|
178
|
+
},
|
|
179
|
+
onDestroy: () => {
|
|
180
|
+
console.log('div destroy'); // вызовется после удаления
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
EL.make('hr', { parent: document.body });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Контекст и экспорт
|
|
188
|
+
function test5() {
|
|
189
|
+
let obj = {}; // контекст
|
|
190
|
+
let arr = []; // массив
|
|
191
|
+
|
|
192
|
+
EL.make('div', { // создать div
|
|
193
|
+
push: arr, // добавить div в массив (переменная arr выше)
|
|
194
|
+
ctx: obj, // контекст для $ и обработчиков (переменная obj выше)
|
|
195
|
+
$: 'myDiv', // создать $myDiv в контексте
|
|
196
|
+
parent: document.body, // прикрепить к body
|
|
197
|
+
child: [ // добавить вложенные
|
|
198
|
+
{
|
|
199
|
+
tag: 'span', // элемент span
|
|
200
|
+
$: 'mySpan', // контекст прокидывается в детей, создать $mySpan
|
|
201
|
+
text: 'text', // с текстом 'text'
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
tag: 'button',
|
|
205
|
+
class: 'btn',
|
|
206
|
+
text: 'say hello',
|
|
207
|
+
onclick: (e) => {
|
|
208
|
+
// e.ctx - контекст
|
|
209
|
+
// обновим текст и цвет mySpan
|
|
210
|
+
e.ctx.$mySpan.update({
|
|
211
|
+
text: 'hello!',
|
|
212
|
+
style: 'color: red',
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
tag: 'button',
|
|
218
|
+
class: 'btn',
|
|
219
|
+
text: 'remove',
|
|
220
|
+
onclick: (e) => {
|
|
221
|
+
e.ctx.$myDiv.remove(); // удалить весь контейнер div
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
console.log(obj); // {$myDiv: div.card, $mySpan: span, $counter: span}
|
|
228
|
+
console.log(arr); // [div.card]
|
|
229
|
+
|
|
230
|
+
// добавим поле для счётчика. Используется контекст родителя
|
|
231
|
+
obj.$myDiv.update({
|
|
232
|
+
child: {
|
|
233
|
+
tag: 'span',
|
|
234
|
+
$: 'counter', // создать $counter в obj
|
|
235
|
+
text: 0,
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// будем менять счётчик по таймеру
|
|
240
|
+
let count = 0;
|
|
241
|
+
setInterval(() => {
|
|
242
|
+
obj.$counter.update({
|
|
243
|
+
text: count++,
|
|
244
|
+
});
|
|
245
|
+
}, 1000);
|
|
246
|
+
|
|
247
|
+
// через 3 сек заменим mySpan на новую кнопку и сохраним в контексте
|
|
248
|
+
setTimeout(() => {
|
|
249
|
+
obj.$mySpan = EL.replace(obj.$mySpan, EL.make('button', {
|
|
250
|
+
class: 'btn',
|
|
251
|
+
text: obj.$mySpan.textContent,
|
|
252
|
+
}));
|
|
253
|
+
}, 3000);
|
|
254
|
+
|
|
255
|
+
EL.make('hr', { parent: document.body });
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Стейты и реактивность
|
|
259
|
+
function test6() {
|
|
260
|
+
// создаём стейт
|
|
261
|
+
let state = new State({ count: 0, name: 'Alex' });
|
|
262
|
+
// можно useState() вместо new State() =)
|
|
263
|
+
|
|
264
|
+
// пример 1 (без стейта)
|
|
265
|
+
EL.make('button', {
|
|
266
|
+
parent: document.body,
|
|
267
|
+
class: 'btn',
|
|
268
|
+
text: 0,
|
|
269
|
+
onclick: (e) => e.el.update({ text: Number(e.el.textContent) + 1 }),
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
// пример 2
|
|
273
|
+
EL.make('button', {
|
|
274
|
+
parent: document.body,
|
|
275
|
+
class: 'btn',
|
|
276
|
+
text: state.bind('count'), // привязываем к count
|
|
277
|
+
onclick: () => {
|
|
278
|
+
state.count += 1; // будет менять text
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// пример 3
|
|
283
|
+
EL.make('button', {
|
|
284
|
+
parent: document.body,
|
|
285
|
+
class: 'btn',
|
|
286
|
+
text: state.bind('count', e => 'Count: ' + e.value), // кастомный вывод
|
|
287
|
+
onclick: () => {
|
|
288
|
+
state.count += 1; // будет менять text
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// пример 4
|
|
293
|
+
EL.make('div', {
|
|
294
|
+
parent: document.body,
|
|
295
|
+
class: 'card',
|
|
296
|
+
child: [
|
|
297
|
+
{
|
|
298
|
+
tag: 'input',
|
|
299
|
+
type: 'text',
|
|
300
|
+
size: 10,
|
|
301
|
+
value: state.name, // значение по умолчанию
|
|
302
|
+
oninput: e => state.name = e.el.value, // меняем
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
tag: 'span',
|
|
306
|
+
text: state.bind('name'), // и меняется тут
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
EL.make('hr', { parent: document.body });
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Shadow DOM
|
|
315
|
+
function test7() {
|
|
316
|
+
EL.makeShadow('div', {
|
|
317
|
+
parent: document.body,
|
|
318
|
+
child: [
|
|
319
|
+
{
|
|
320
|
+
class: 'myclass',
|
|
321
|
+
child: {
|
|
322
|
+
text: 'I am shadow!',
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
'.myclass{color:red;}'
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
EL.make('hr', { parent: document.body });
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Шаблоны компонентов
|
|
334
|
+
function test8() {
|
|
335
|
+
// через глобальный шаблон EL
|
|
336
|
+
EL.setTemplate('userCard', 'div', (name, lastname, birthdate) => ({
|
|
337
|
+
class: 'card',
|
|
338
|
+
child: [
|
|
339
|
+
{ tag: 'h3', text: `${name} ${lastname}` },
|
|
340
|
+
{ tag: 'p', text: `Birthdate: ${birthdate}` }
|
|
341
|
+
]
|
|
342
|
+
}));
|
|
343
|
+
|
|
344
|
+
EL.useTemplate('userCard', 'Alice', 'Smith', '1995-06-12').mount(document.body);
|
|
345
|
+
EL.useTemplate('userCard', 'Bob', 'Johnson', '1990-01-01').mount(document.body);
|
|
346
|
+
|
|
347
|
+
// вручную + родитель
|
|
348
|
+
const myTemplate = (name, lastname, birthdate, parent) => (EL.make('div', {
|
|
349
|
+
class: 'card',
|
|
350
|
+
parent,
|
|
351
|
+
child: [
|
|
352
|
+
{ tag: 'h3', text: `${name} ${lastname}` },
|
|
353
|
+
{ tag: 'p', text: `Birthdate: ${birthdate}` }
|
|
354
|
+
]
|
|
355
|
+
}));
|
|
356
|
+
|
|
357
|
+
myTemplate('Alice', 'Smith', '1995-06-12', document.body);
|
|
358
|
+
myTemplate('Bob', 'Johnson', '1990-01-01', document.body);
|
|
359
|
+
|
|
360
|
+
// фабрика конфигурации
|
|
361
|
+
|
|
362
|
+
const myButton = (text, color) => ({
|
|
363
|
+
tag: 'button',
|
|
364
|
+
text: text,
|
|
365
|
+
style: {
|
|
366
|
+
_raw: 'padding: 5px 10px; color: white; border: none; border-radius: 4px; margin: 0 5px;',
|
|
367
|
+
backgroundColor: color,
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
EL.make('div', {
|
|
372
|
+
class: 'card',
|
|
373
|
+
parent: document.body,
|
|
374
|
+
child: [
|
|
375
|
+
myButton('hello', 'red'),
|
|
376
|
+
myButton('world', 'blue'),
|
|
377
|
+
myButton('kek', 'green'),
|
|
378
|
+
]
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
EL.make('hr', { parent: document.body });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Анимации
|
|
385
|
+
function test9() {
|
|
386
|
+
EL.make('div', {
|
|
387
|
+
// анимируем и удаляем после завершения
|
|
388
|
+
parent: document.body,
|
|
389
|
+
style: { width: '50px', height: '50px', backgroundColor: 'orange' },
|
|
390
|
+
transition: {
|
|
391
|
+
width: '150px', height: '150px',
|
|
392
|
+
duration: 1500, onEnd: (e) => e.el.remove()
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
EL.make('hr', { parent: document.body });
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// SVG
|
|
400
|
+
function test10() {
|
|
401
|
+
let circ = SVG.make_circle(100, 100, 30, { fill: 'red' });
|
|
402
|
+
|
|
403
|
+
SVG.make_svg({ width: 200, height: 200 }, {
|
|
404
|
+
parent: document.body,
|
|
405
|
+
style: 'border: 1px solid #ccc',
|
|
406
|
+
child: [
|
|
407
|
+
// вручную
|
|
408
|
+
{
|
|
409
|
+
tag: 'rect',
|
|
410
|
+
attrs: {
|
|
411
|
+
x: 10,
|
|
412
|
+
y: 130,
|
|
413
|
+
width: 50,
|
|
414
|
+
height: 50,
|
|
415
|
+
fill: 'green',
|
|
416
|
+
}
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
// внешний
|
|
420
|
+
circ,
|
|
421
|
+
|
|
422
|
+
// билдеры
|
|
423
|
+
SVG.rect(10, 10, 50, 50, 5, 5, { fill: 'blue' }),
|
|
424
|
+
SVG.line(0, 0, 200, 200, { stroke: 'black', 'stroke-width': 2 })
|
|
425
|
+
],
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
EL.make('hr', { parent: document.body });
|
|
429
|
+
|
|
430
|
+
// двигаем кружок
|
|
431
|
+
setInterval(() => {
|
|
432
|
+
circ.update({ attrs: { cx: Math.random() * 200, cy: Math.random() * 200 } })
|
|
433
|
+
}, 300);
|
|
434
|
+
}
|
package/webpack.config.js
CHANGED
|
@@ -1,14 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const CompressionPlugin = require('compression-webpack-plugin');
|
|
2
|
+
|
|
3
|
+
const makeConfig = (flags, filename) => ({
|
|
4
|
+
entry: './src/Component.js',
|
|
3
5
|
output: {
|
|
4
6
|
path: __dirname,
|
|
5
|
-
filename
|
|
6
|
-
library: {
|
|
7
|
-
type: 'module'
|
|
8
|
-
}
|
|
7
|
+
filename,
|
|
8
|
+
library: { type: 'module' }
|
|
9
9
|
},
|
|
10
|
-
experiments: {
|
|
11
|
-
|
|
10
|
+
experiments: { outputModule: true },
|
|
11
|
+
module: {
|
|
12
|
+
rules: [
|
|
13
|
+
{
|
|
14
|
+
test: /\.js$/,
|
|
15
|
+
loader: 'ifdef-loader',
|
|
16
|
+
options: flags
|
|
17
|
+
}
|
|
18
|
+
]
|
|
12
19
|
},
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
plugins: [
|
|
21
|
+
new CompressionPlugin({
|
|
22
|
+
algorithm: 'gzip',
|
|
23
|
+
test: /\.js$/,
|
|
24
|
+
})
|
|
25
|
+
],
|
|
26
|
+
mode: 'production'
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
module.exports = [
|
|
30
|
+
makeConfig({ TINY_COMPONENT: false, PICO_COMPONENT: false }, 'Component.min.js'),
|
|
31
|
+
makeConfig({ TINY_COMPONENT: true, PICO_COMPONENT: false }, 'Component.tiny.min.js'),
|
|
32
|
+
makeConfig({ TINY_COMPONENT: true, PICO_COMPONENT: true }, 'Component.pico.min.js'),
|
|
33
|
+
];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
entry: './test/script.js',
|
|
5
|
+
output: {
|
|
6
|
+
filename: 'script.js',
|
|
7
|
+
path: path.resolve(__dirname, 'test'),
|
|
8
|
+
clean: false,
|
|
9
|
+
},
|
|
10
|
+
module: {
|
|
11
|
+
rules: [
|
|
12
|
+
{
|
|
13
|
+
test: /\.css$/,
|
|
14
|
+
use: ['style-loader', 'css-loader'],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
// test: /\.js$/,
|
|
18
|
+
// loader: 'ifdef-loader',
|
|
19
|
+
// options: {
|
|
20
|
+
// TINY_COMPONENT: true,
|
|
21
|
+
// PICO_COMPONENT: true,
|
|
22
|
+
// }
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
devServer: {
|
|
27
|
+
static: path.resolve(__dirname, 'test'),
|
|
28
|
+
hot: true,
|
|
29
|
+
open: true,
|
|
30
|
+
},
|
|
31
|
+
mode: 'development',
|
|
32
|
+
};
|