@caweb/html-webpack-plugin 2.0.1 → 2.0.2
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/CHANGELOG.md +3 -0
- package/index.js +169 -135
- package/package.json +16 -9
- package/tests/webpack.tests.js +32 -0
package/CHANGELOG.md
CHANGED
package/index.js
CHANGED
|
@@ -15,11 +15,58 @@ const boldWhite = chalk.bold.white;
|
|
|
15
15
|
const boldGreen = chalk.bold.green;
|
|
16
16
|
const boldBlue = chalk.bold.hex('#03a7fc');
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
// this is the current project directory
|
|
19
19
|
const appPath = process.cwd();
|
|
20
|
-
const templatePath = path.resolve(currentPath, '..', 'template');
|
|
21
|
-
const iconLibraryPath = path.resolve(currentPath, '..', 'icon-library');
|
|
22
20
|
|
|
21
|
+
// this is the path to this current file
|
|
22
|
+
const currentPath = path.dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
// this should be the path to the @caweb/template and @caweb/icon-library packages
|
|
25
|
+
const templatePath = path.join( 'node_modules', '@caweb', 'template');
|
|
26
|
+
const iconLibraryPath = path.join( 'node_modules', '@caweb', 'icon-library');
|
|
27
|
+
|
|
28
|
+
const allowedAssetExts = [
|
|
29
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg',
|
|
30
|
+
'.bmp', '.gif', '.ico',
|
|
31
|
+
'.woff', '.woff2', '.eot', '.ttf', '.otf'
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
// function to process assets from regex matches
|
|
35
|
+
const processAssets = ( assets = [] , type = 'style') => {
|
|
36
|
+
let temp = [];
|
|
37
|
+
|
|
38
|
+
if( ! assets ){
|
|
39
|
+
return temp;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if( 'style' === type ){
|
|
43
|
+
temp = assets
|
|
44
|
+
.map( a => {
|
|
45
|
+
return a
|
|
46
|
+
.replace(/(style=".*url\(\s*)(\S+)\s*\)/g, '$2') // get url() content
|
|
47
|
+
.replace(/((src|href)=")(\S+)".*/g, '$3') // remove src=" or href="
|
|
48
|
+
// .replace(/['"]/g, '') // remove quotes
|
|
49
|
+
})
|
|
50
|
+
} else {
|
|
51
|
+
temp = assets // map to extract just the asset file
|
|
52
|
+
.map( a => {
|
|
53
|
+
return a
|
|
54
|
+
.replace(/((src|href)=")/g, '') // remove src=" or href="
|
|
55
|
+
// .replace(/".*/g, '') // remove anything after the first "
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return temp
|
|
60
|
+
// filter to only include local files with allowed extensions
|
|
61
|
+
.filter( asset => {
|
|
62
|
+
let ext = path.extname( asset ).toLowerCase();
|
|
63
|
+
let localFile = fs.existsSync( path.join( appPath, asset ) )
|
|
64
|
+
|
|
65
|
+
return localFile && allowedAssetExts.includes( ext );
|
|
66
|
+
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
23
70
|
/**
|
|
24
71
|
* Launches CAWeb HTML Markup
|
|
25
72
|
*
|
|
@@ -36,91 +83,93 @@ class CAWebHtmlWebpackPlugin extends HtmlWebpackPlugin{
|
|
|
36
83
|
|
|
37
84
|
// we change some of the html-webpack-plugin defaults
|
|
38
85
|
constructor(opts = {}) {
|
|
39
|
-
|
|
40
|
-
|
|
86
|
+
// the available templates in @caweb/template
|
|
87
|
+
let templates = ['blank', 'default', 'search'];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Default options
|
|
91
|
+
* we use the @caweb/template package as the default template source
|
|
92
|
+
*
|
|
93
|
+
* @see https://github.com/jantimon/html-webpack-plugin/blob/main/index.js
|
|
94
|
+
*/
|
|
41
95
|
let defaultOptions = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
96
|
+
// we use the @caweb/template patterns/default.html as the default template
|
|
97
|
+
template: path.join( templatePath, 'patterns', 'default.html'),
|
|
98
|
+
|
|
99
|
+
// favicon
|
|
100
|
+
favicon: path.join( templatePath, 'media', 'favicon.ico' ),
|
|
101
|
+
|
|
102
|
+
// variables to pass to the template
|
|
46
103
|
templateParameters: {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
104
|
+
// site title
|
|
105
|
+
title: path.basename( appPath ),
|
|
106
|
+
|
|
107
|
+
//site color scheme
|
|
108
|
+
scheme: 'oceanside',
|
|
109
|
+
|
|
110
|
+
// site logo, default is the @caweb/template/media/logo.png
|
|
111
|
+
logo: path.join(templatePath, 'media', 'logo.png'),
|
|
112
|
+
|
|
113
|
+
// meta tags
|
|
114
|
+
meta: {
|
|
115
|
+
Author: "CAWebPublishing",
|
|
116
|
+
Description: "State of California",
|
|
117
|
+
Keywords: "CAWebPublishing, California, government",
|
|
118
|
+
viewport: "width=device-width, initial-scale=1.0, maximum-scale=2.0"
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// array of additional assets to include
|
|
122
|
+
// this might be removed in the future
|
|
123
|
+
assets: []
|
|
56
124
|
},
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
// array of additional assets to include
|
|
128
|
+
// this might be removed in the future
|
|
57
129
|
assets: []
|
|
58
|
-
}
|
|
130
|
+
};
|
|
59
131
|
|
|
60
132
|
// if there is a favicon.ico file in the media directory we use that
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
path.join(appPath, 'media', 'favicon.ico') :
|
|
64
|
-
path.join(templatePath, 'media', 'favicon.ico');
|
|
65
|
-
|
|
66
|
-
// the templateParameters.favicon is not set, set it
|
|
67
|
-
if( ! defaultOptions.templateParameters.favicon ){
|
|
68
|
-
defaultOptions.templateParameters.favicon = defaultOptions.favicon;
|
|
133
|
+
if( fs.existsSync(path.join(appPath, 'media', 'favicon.ico')) ){
|
|
134
|
+
defaultOptions.favicon = path.join(appPath, 'media', 'favicon.ico');
|
|
69
135
|
}
|
|
70
136
|
|
|
71
137
|
// if there is a logo file in the media directory we use that
|
|
72
138
|
if( fs.existsSync(path.join(appPath, 'media', 'logo.png')) ){
|
|
73
|
-
defaultOptions.assets.push( path.join(appPath, 'media', 'logo.png') );
|
|
139
|
+
// defaultOptions.assets.push( path.join(appPath, 'media', 'logo.png') );
|
|
74
140
|
defaultOptions.templateParameters.logo = '/media/logo.png';
|
|
75
|
-
|
|
76
|
-
// otherwise we fallback to the template logo.png
|
|
77
|
-
}else{
|
|
78
|
-
// remove the appPath from the templath path
|
|
79
|
-
// replace all backslashes with forward slashes
|
|
80
|
-
// this is to make sure the logo.png in the branding.html is in the right place
|
|
81
|
-
defaultOptions.templateParameters.logo =
|
|
82
|
-
path.join(
|
|
83
|
-
templatePath,
|
|
84
|
-
'media', 'logo.png'
|
|
85
|
-
)
|
|
86
|
-
.replace(appPath, '')
|
|
87
|
-
.replace(/\\/g, '/');
|
|
88
141
|
}
|
|
89
142
|
|
|
90
|
-
// update templateParameters.title to match user options.
|
|
91
|
-
if( opts.title ){
|
|
92
|
-
defaultOptions.templateParameters.title = opts.title;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
143
|
// if template selection is one of ours
|
|
96
144
|
if( opts.template && templates.includes(opts.template) ){
|
|
97
|
-
let template = 'default' === opts.template ? 'index' : opts.template;
|
|
98
145
|
|
|
99
146
|
// update template file based on template selection
|
|
100
|
-
opts.template = path.join( templatePath, 'patterns', `${template}.html`);
|
|
101
|
-
|
|
102
|
-
// update default.templateParameters.template to match user options.
|
|
103
|
-
defaultOptions.templateParameters.template = template;
|
|
147
|
+
opts.template = path.join( templatePath, 'patterns', `${opts.template}.html`);
|
|
104
148
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* the html-webpack-plugin meta tags are missing the self closing forward slash
|
|
152
|
+
* so if the user options has meta tags, we move them to the opts.templateParameters.meta
|
|
153
|
+
* and delete the opts.meta key
|
|
154
|
+
*/
|
|
108
155
|
if( opts.meta ){
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
...opts.meta
|
|
112
|
-
}
|
|
156
|
+
// ensure templateParameters exists
|
|
157
|
+
opts.templateParameters = opts.templateParameters || {};
|
|
113
158
|
|
|
159
|
+
// move opts.meta to opts.templateParameters.meta
|
|
160
|
+
opts.templateParameters.meta = opts.meta
|
|
161
|
+
|
|
162
|
+
// delete opts.meta
|
|
114
163
|
delete opts.meta;
|
|
115
164
|
}
|
|
116
165
|
|
|
117
166
|
// if there is a caweb.json file we merge the site data with the templateParameters
|
|
118
167
|
if( fs.existsSync( path.join(appPath, 'caweb.json') ) ){
|
|
119
|
-
|
|
120
168
|
let dataFile = JSON.parse( fs.readFileSync( path.join(appPath, 'caweb.json') ) );
|
|
121
|
-
|
|
169
|
+
|
|
122
170
|
// if there is a dataFile.site
|
|
123
171
|
if( dataFile.site ){
|
|
172
|
+
|
|
124
173
|
// we remove the title key from the dataFile.site
|
|
125
174
|
// this is to avoid overwriting the title set in the defaultOptions.templateParameters
|
|
126
175
|
if( dataFile.site.title ){
|
|
@@ -134,8 +183,8 @@ class CAWebHtmlWebpackPlugin extends HtmlWebpackPlugin{
|
|
|
134
183
|
...dataFile.site
|
|
135
184
|
}
|
|
136
185
|
|
|
137
|
-
// some properties are used in different ways and not as templateParameters
|
|
138
|
-
// if there is a dataFile.site.favicon we
|
|
186
|
+
// some properties are used in different ways and not just as templateParameters
|
|
187
|
+
// if there is a dataFile.site.favicon we have to define that outside of the templateParameters
|
|
139
188
|
if( dataFile.site.favicon ){
|
|
140
189
|
defaultOptions.favicon = dataFile.site.favicon;
|
|
141
190
|
}
|
|
@@ -143,6 +192,7 @@ class CAWebHtmlWebpackPlugin extends HtmlWebpackPlugin{
|
|
|
143
192
|
|
|
144
193
|
}
|
|
145
194
|
|
|
195
|
+
// call the parent class constructor with the merged options
|
|
146
196
|
super(deepmerge(defaultOptions, opts));
|
|
147
197
|
|
|
148
198
|
}
|
|
@@ -161,45 +211,29 @@ class CAWebHtmlWebpackPlugin extends HtmlWebpackPlugin{
|
|
|
161
211
|
({html, outputName, plugin}, cb) => {
|
|
162
212
|
// if the html contains local assets those assets are added to the options.assets array
|
|
163
213
|
// and the assets are added to the compilation afterEmit
|
|
164
|
-
let srcHrefAssets = html.match(/(src|href)="(
|
|
165
|
-
let styleAssets = html.match(/style=".*url\((\S+)\)/g);
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
//
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// if the asset is a local file
|
|
189
|
-
// if the asset is not already in the options.assets array
|
|
190
|
-
if(
|
|
191
|
-
fs.existsSync(localFile) &&
|
|
192
|
-
fs.lstatSync(localFile).isFile() &&
|
|
193
|
-
! this.options.assets.includes(localFile)
|
|
194
|
-
){
|
|
195
|
-
this.options.assets.push(localFile);
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// any references to the node_modules directory are removed
|
|
200
|
-
// any organizational packages @ are also removed
|
|
201
|
-
// this might cause some conflicts with packages that are named the same as organiazational packages
|
|
202
|
-
html = html.replace(/[\\\/]?node_modules[\\\/@]+/g, '/');
|
|
214
|
+
// let srcHrefAssets = processAssets(html.match(/(src|href)="(.+)"/g));
|
|
215
|
+
// let styleAssets = processAssets(html.match(/style=".*url\((\S+)\)/g));
|
|
216
|
+
// let allAssets = [ ...new Set([
|
|
217
|
+
// ...srcHrefAssets,
|
|
218
|
+
// ...styleAssets
|
|
219
|
+
// ])
|
|
220
|
+
// ];
|
|
221
|
+
|
|
222
|
+
// allAssets.forEach( asset =>{
|
|
223
|
+
// let localFile = asset.startsWith('/') || asset.startsWith('\\') ?
|
|
224
|
+
// path.join( appPath, asset ) :
|
|
225
|
+
// asset;
|
|
226
|
+
|
|
227
|
+
// // if the asset is a local file
|
|
228
|
+
// // if the asset is not already in the options.assets array
|
|
229
|
+
// if(
|
|
230
|
+
// fs.existsSync(localFile) &&
|
|
231
|
+
// fs.lstatSync(localFile).isFile() &&
|
|
232
|
+
// ! this.options.assets.includes(localFile)
|
|
233
|
+
// ){
|
|
234
|
+
// this.options.assets.push(localFile);
|
|
235
|
+
// }
|
|
236
|
+
// });
|
|
203
237
|
|
|
204
238
|
// Tell webpack to move on
|
|
205
239
|
cb(null, {html, outputName, plugin});
|
|
@@ -212,41 +246,41 @@ class CAWebHtmlWebpackPlugin extends HtmlWebpackPlugin{
|
|
|
212
246
|
|
|
213
247
|
// if there are any assets in the options.assets array
|
|
214
248
|
// we add them to the compilation and emit them
|
|
215
|
-
this.options.assets.forEach( async (asset) => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
249
|
+
// this.options.assets.forEach( async (asset) => {
|
|
250
|
+
// compilation.fileDependencies.add( asset );
|
|
251
|
+
|
|
252
|
+
// // we remove the appPath from the asset path
|
|
253
|
+
// // we remove the node_modules/@ from the asset path
|
|
254
|
+
// compilation.emitAsset(
|
|
255
|
+
// asset.replace(appPath, '').replace(/[\\\/]?node_modules[\\\/@]+/g, ''),
|
|
256
|
+
// new compiler.webpack.sources.RawSource( fs.readFileSync(asset) )
|
|
257
|
+
// );
|
|
258
|
+
|
|
259
|
+
// // if the asset is the @caweb/icon-library font-only.css file we have to also add the font files
|
|
260
|
+
// if( asset.match(/@caweb\/icon-library\/build\/font-only-?.*.css/g) ){
|
|
261
|
+
// let fontPath = path.join( iconLibraryPath, 'build', 'fonts' );
|
|
262
|
+
|
|
263
|
+
// let fontFiles = fs.readdirSync(fontPath).filter( (file) => {
|
|
264
|
+
// return file.endsWith('.woff') ||
|
|
265
|
+
// file.endsWith('.woff2') ||
|
|
266
|
+
// file.endsWith('.eot') ||
|
|
267
|
+
// file.endsWith('.svg') ||
|
|
268
|
+
// file.endsWith('.ttf');
|
|
269
|
+
// });
|
|
270
|
+
|
|
271
|
+
// fontFiles.forEach( (file) => {
|
|
272
|
+
// compilation.fileDependencies.add( file );
|
|
273
|
+
|
|
274
|
+
// let filePath = path.join( fontPath, file );
|
|
241
275
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
});
|
|
276
|
+
// // we remove the appPath from the asset path
|
|
277
|
+
// compilation.emitAsset(
|
|
278
|
+
// filePath.replace(appPath, '').replace(/[\\\/]?node_modules[\\\/@]+/g, ''),
|
|
279
|
+
// new compiler.webpack.sources.RawSource( fs.readFileSync(filePath) )
|
|
280
|
+
// );
|
|
281
|
+
// });
|
|
282
|
+
// }
|
|
283
|
+
// });
|
|
250
284
|
|
|
251
285
|
// Tell webpack to move on
|
|
252
286
|
cb(null, {outputName, plugin});
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caweb/html-webpack-plugin",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "CAWebPublishing Site Generation HTML Webpack Plugin",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
"author": "CAWebPublishing",
|
|
8
|
+
"license": "ISC",
|
|
9
|
+
"homepage": "https://github.com/CAWebPublishing/webpack/plugins/html#readme",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/CAWebPublishing/webpack.git",
|
|
@@ -18,19 +18,26 @@
|
|
|
18
18
|
"webpack",
|
|
19
19
|
"html-webpack-plugin"
|
|
20
20
|
],
|
|
21
|
-
"author": "CAWebPublishing",
|
|
22
|
-
"license": "ISC",
|
|
23
21
|
"bugs": {
|
|
24
22
|
"url": "https://github.com/CAWebPublishing/webpack/issues"
|
|
25
23
|
},
|
|
26
24
|
"publishConfig": {
|
|
27
25
|
"access": "public"
|
|
28
26
|
},
|
|
29
|
-
"homepage": "https://github.com/CAWebPublishing/webpack/plugins/html#readme",
|
|
30
27
|
"dependencies": {
|
|
28
|
+
"@caweb/framework": "^1.9.2",
|
|
29
|
+
"@caweb/icon-library": "^1.1.6",
|
|
30
|
+
"@caweb/template": "^1.0.12",
|
|
31
31
|
"html-webpack-plugin": "^5.6.6"
|
|
32
32
|
},
|
|
33
|
-
"
|
|
34
|
-
"
|
|
33
|
+
"scripts": {
|
|
34
|
+
"webpack": "webpack",
|
|
35
|
+
"test:build": "webpack build --config ./node_modules/@caweb/webpack/webpack.config.js",
|
|
36
|
+
"test:serve": "webpack serve --config ./node_modules/@caweb/webpack/webpack.config.js ./tests/webpack.tests.js --merge",
|
|
37
|
+
"test": "echo \"Error: run tests from root\" && exit 0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"webpack": "^5.104.1",
|
|
41
|
+
"webpack-cli": "^6.0.1"
|
|
35
42
|
}
|
|
36
43
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* These are tests for the CAWeb HTML Webpack Plugin
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* External Dependencies
|
|
7
|
+
*/
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Internal Dependencies
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// we import this current plugin to test it
|
|
15
|
+
import CAWebHtmlWebpackPlugin from '../index.js';
|
|
16
|
+
|
|
17
|
+
export default {
|
|
18
|
+
plugins: [
|
|
19
|
+
new CAWebHtmlWebpackPlugin({
|
|
20
|
+
templateParameters: {
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
],
|
|
24
|
+
devServer: {
|
|
25
|
+
static: [
|
|
26
|
+
// we all serving the local template media files for testing
|
|
27
|
+
{
|
|
28
|
+
directory: path.join( process.cwd(), '..', 'template', 'media' ),
|
|
29
|
+
},
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
};
|