@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 CHANGED
@@ -1,3 +1,6 @@
1
+ v2.0.2
2
+ - No longer emitting src/href/styles assets
3
+
1
4
  v2.0.1
2
5
  - Updated npm packages
3
6
 
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
- const currentPath = path.dirname(fileURLToPath(import.meta.url));
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
- let templates = ['index', 'blank', 'default', 'search'];
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
- title: path.basename( appPath ),
43
- inject: 'body',
44
- template: path.join( templatePath, 'patterns', 'index.html'),
45
- scriptLoading: 'blocking',
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
- "template": "index",
48
- "title": path.basename( appPath ),
49
- "scheme": "oceanside",
50
- "meta": {
51
- "Author": "CAWebPublishing",
52
- "Description": "State of California",
53
- "Keywords": "California,government",
54
- "viewport": "width=device-width, initial-scale=1.0, maximum-scale=2.0"
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
- // otherwise we fallback to the template favicon.ico
62
- defaultOptions.favicon = fs.existsSync(path.join(appPath, 'media', 'favicon.ico')) ?
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
- // if the user options has meta tags we merge them with the defaultOptions.templateParameters.meta
107
- // and clear the meta key
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
- defaultOptions.templateParameters.meta = {
110
- ...defaultOptions.templateParameters.meta,
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 use that
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)="(.+?)"/g);
165
- let styleAssets = html.match(/style=".*url\((\S+)\)/g);
166
-
167
- let allAssets = [];
168
-
169
- // if the html contains url() in the style attributes
170
- if( styleAssets ){
171
- styleAssets = styleAssets.map( s => s.replace(/(style=".*url\(|["'()])/g, '') )
172
- // |["'\(\)]
173
- allAssets = [...allAssets, ...styleAssets];
174
- }
175
-
176
- // if the html contains src or href attributes
177
- if( srcHrefAssets ){
178
- srcHrefAssets = srcHrefAssets.map( s => s.replace(/(src|href|=|")/g, '') );
179
-
180
- allAssets = [...allAssets, ...srcHrefAssets];
181
- }
182
-
183
- allAssets.forEach( asset =>{
184
- let localFile = asset.startsWith('/') || asset.startsWith('\\') ?
185
- path.join( appPath, asset ) :
186
- asset;
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
- compilation.fileDependencies.add( asset );
217
-
218
- // we remove the appPath from the asset path
219
- // we remove the node_modules/@ from the asset path
220
- compilation.emitAsset(
221
- asset.replace(appPath, '').replace(/[\\\/]?node_modules[\\\/@]+/g, ''),
222
- new compiler.webpack.sources.RawSource( fs.readFileSync(asset) )
223
- );
224
-
225
- // if the asset is the @caweb/icon-library font-only.css file we have to also add the font files
226
- if( asset.match(/@caweb\/icon-library\/build\/font-only-?.*.css/g) ){
227
- let fontPath = path.join( iconLibraryPath, 'build', 'fonts' );
228
-
229
- let fontFiles = fs.readdirSync(fontPath).filter( (file) => {
230
- return file.endsWith('.woff') ||
231
- file.endsWith('.woff2') ||
232
- file.endsWith('.eot') ||
233
- file.endsWith('.svg') ||
234
- file.endsWith('.ttf');
235
- });
236
-
237
- fontFiles.forEach( (file) => {
238
- compilation.fileDependencies.add( file );
239
-
240
- let filePath = path.join( fontPath, file );
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
- // we remove the appPath from the asset path
243
- compilation.emitAsset(
244
- filePath.replace(appPath, '').replace(/[\\\/]?node_modules[\\\/@]+/g, ''),
245
- new compiler.webpack.sources.RawSource( fs.readFileSync(filePath) )
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.1",
3
+ "version": "2.0.2",
4
4
  "description": "CAWebPublishing Site Generation HTML Webpack Plugin",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
- "scripts": {
8
- "test": "echo \"Error: run tests from root\" && exit 0"
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
- "peerDependencies": {
34
- "@caweb/template": "^1.0.6"
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
+ };