Skip to content
This repository was archived by the owner on Apr 5, 2021. It is now read-only.

v3.3.0

Choose a tag to compare

@mmiller42 mmiller42 released this 16 Sep 01:40
· 73 commits to master since this release

What's New in v3.3.0

This is a summary of the differences between v3.3.0 and v3.2.0.

Commits

Show commits
SHA Author Message
b0a5d0c mmiller42 Allow type to be manually specified for assets. Will require merge and release of jharris4/html-webpack-tags-plugin#8
b984710 mmiller42 checking off on roadmap
6d9e1b1 mmiller42 Footnote for using hash
6437e12 mmiller42 Merge branch 'master' into override-type
# Conflicts:
# ROADMAP.md
96d2c39 mmiller42 Merge branch 'master' into override-type
8d3d373 mmiller42 Adding tons and tons of examples to the docs
30a2845 mmiller42 Clarifying a couple of options
f8fdfe6 mmiller42 Upgrading html-webpack-include-assets-plugin
0ab1491 mmiller42 3.3.0

Changed files

README.md

Show changes
@@ -43,7 +43,7 @@ The constructor takes a configuration object with the following properties.
 | --- | --- | --- | --- |
 | \`externals\` | array<object> | An array of vendor modules that will be excluded from your Webpack bundle and added as \`script\` or \`link\` tags in your HTML output. | *None* |
 | \`externals[].module\` | string | The name of the vendor module. This should match the package name, e.g. if you are writing \`import React from 'react'\`, this would be \`react\`. | *None* |
-| \`externals[].entry\` | string \| array<string> | The path, relative to the vendor module directory, to its pre-bundled distro file. e.g. for React, use \`dist/react.js\`, since the file exists at \`node_modules/react/dist/react.js\`. Specify an array if there are multiple CSS/JS files to inject. To use a CDN instead, simply use a fully qualified URL beginning with \`http://\`, \`https://\`, or \`//\`. | *None* |
+| \`externals[].entry\` | string \| array&lt;string&gt; \| object \| array&lt;object \| string&gt; | The path, relative to the vendor module directory, to its pre-bundled distro file. e.g. for React, use \`dist/react.js\`, since the file exists at \`node_modules/react/dist/react.js\`. Specify an array if there are multiple CSS/JS files to inject. To use a CDN instead, simply use a fully qualified URL beginning with \`http://\`, \`https://\`, or \`//\`.<br><br>For entries whose type (JS or CSS) cannot be inferred by file extension, pass an object such as \`{ path: 'https://some/url', type: 'css' }\` (or \`type: 'js'\`). | *None* |
 | \`externals[].global\` | string \| null | For JavaScript modules, this is the name of the object globally exported by the vendor's dist file. e.g. for React, use \`React\`, since \`react.js\` creates a \`window.React\` global. For modules without an export (such as CSS), omit this property or use \`null\`. | \`null\` |
 | \`externals[].supplements\` | array&lt;string&gt; | For modules that require additional resources, specify globs of files to copy over to the output. e.g. for Bootstrap CSS, use \`['dist/fonts/']\`, since Glyphicon fonts are referenced in the CSS and exist at \`node_modules/bootstrap/dist/fonts/\`. | \`[]\` |
 | \`externals[].append\` | boolean | Set to true to inject this module after your Webpack bundles. | \`false\` |
@@ -52,35 +52,236 @@ The constructor takes a configuration object with the following properties.
 | \`publicPath\` | string \| null | Override Webpack config's \`publicPath\` for the externals files, or \`null\` to use the default \`output.publicPath\` value. | \`null\` |
 | \`files\` | string \| array&lt;string&gt; \| null | If you have multiple instances of HtmlWebpackPlugin, use this to specify globs of which files you want to inject assets into. Will add assets to all files by default. | \`null\` |
 
-## Example
+## Examples
+
+### Local JS external example
+
+This example assumes \`jquery\` is installed in the app. It:
+
+1. adds \`jquery\` to your Webpack config's \`externals\` object to exclude it from your bundle, telling it to expect a global object called \`jQuery\` (on the \`window\` object)
+1. copies \`node_modules/jquery/dist/jquery.min.js\` to \`<output path>/vendor/jquery/dist/jquery.min.js\`
+1. adds \`<script type="text/javascript" src="<public path>/vendor/jquery/dist/jquery.min.js"></script>\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'jquery',
+      entry: 'dist/jquery.min.js',
+      global: 'jQuery',
+    },
+  ],
+})
+\`\`\`
+
+### Local CSS external example
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+    },
+  ],
+})
+\`\`\`
+
+### Local external with supplemental assets example
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. copies all contents of \`node_modules/bootstrap/dist/fonts/\` to \`<output path>/vendor/bootstrap/dist/fonts/\`
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+      supplements: ['dist/fonts/'],
+    },
+  ],
+})
+\`\`\`
+
+### CDN example
+
+This example does not require the \`jquery\` module to be installed. It:
+
+1. adds \`jquery\` to your Webpack config's \`externals\` object to exclude it from your bundle, telling it to expect a global object called \`jQuery\` (on the \`window\` object)
+1. adds \`<script type="text/javascript" src="https://unpkg.com/jquery@3.2.1/dist/jquery.min.js"></script>\` to your HTML file, before your chunks
 
 \`\`\`js
 new HtmlWebpackExternalsPlugin({
   externals: [
     {
-      // Specify that \`react\` module will be externalized (not bundled)
-      module: 'react',
-      // Copy \`node_modules/react/dist/react.js\` into output and insert \`script\` tag
-      entry: 'dist/react.js',
-      // Specify that the \`react\` module is accessed via \`window.React\`
-      global: 'React',
+      module: 'jquery',
+      entry: 'https://unpkg.com/jquery@3.2.1/dist/jquery.min.js',
+      global: 'jQuery',
     },
+  ],
+})
+\`\`\`
+
+### URL without implicit extension example
+
+Some CDN URLs don't have file extensions, so the plugin cannot determine whether to use a \`link\` tag or a \`script\` tag. In these situations, you can pass an object in place of the \`entry\` property that specifies the path and type explicitly.
+
+This example uses the Google Fonts API to load the Roboto font. It:
+
+1. adds \`<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
     {
-      module: 'react-dom',
-      entry: 'dist/react-dom.js',
-      global: 'ReactDOM',
+      module: 'google-roboto',
+      entry: {
+        path: 'https://fonts.googleapis.com/css?family=Roboto',
+        type: 'css',
+      },
     },
+  ],
+})
+\`\`\`
+
+### Module with multiple entry points example
+
+Some modules require more than one distro file to be loaded. For example, Bootstrap has a normal and a theme CSS entry point.
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. copies \`node_modules/bootstrap/dist/css/bootstrap-theme.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap-theme.min.css\`
+1. copies all contents of \`node_modules/bootstrap/dist/fonts/\` to \`<output path>/vendor/bootstrap/dist/fonts/\`
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap-theme.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
     {
       module: 'bootstrap',
-      // Specify multiple entry points to copy into output and insert a \`link\` tag for each
-      entry: ['dist/css/bootstrap.css', 'dist/css/bootstrap-theme.css'],
-      // Specify additional assets to copy into the outputPath, needed by this module
+      entry: ['dist/css/bootstrap.min.css', 'dist/css/bootstrap-theme.min.css'],
       supplements: ['dist/fonts/'],
     },
   ],
-  // Enable cache-busting on the module entry files
+})
+\`\`\`
+
+### Appended assets example
+
+Sometimes you want to load the external after your Webpack chunks instead of before.
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, *after* your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+      append: true,
+    },
+  ],
+})
+\`\`\`
+
+### Cache-busting with hashes example
+
+You can configure the plugin to append hashes to the query string on the HTML tags so that, when upgrading modules, a new hash is computed, busting your app users' caches. **Do not use this in tandem with CDNs, only when using local externals.**
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="<public path>/vendor/bootstrap/dist/css/bootstrap.min.css?<unique hash>" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+    },
+  ],
   hash: true,
-  // Specify the directory within the outputPath to copy externals' assets into
-  outputPath: 'vendors',
+})
+\`\`\`
+
+### Customizing output path example
+
+By default, local externals are copied into the Webpack output directory, into a subdirectory called \`vendor\`. This is configurable.
+
+Do not include a trailing slash or leading slash in your output path, they are concatenated automatically by the plugin.
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/thirdparty/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="<public path>/thirdparty/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+    },
+  ],
+  outputPath: 'thirdparty',
+})
+\`\`\`
+
+### Customizing public path example
+
+By default, local externals are resolved from the same root path as your Webpack configuration file's \`output.publicPath\`, concatenated with the \`outputPath\` variable. This is configurable.
+
+You should include a trailing slash in your public path, and a leading slash if you want it to resolve assets from the domain root.
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="/public/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to your HTML file, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+    },
+  ],
+  publicPath: '/assets/',
+})
+\`\`\`
+
+### Specifying which HTML files to affect example
+
+If you are using multiple instances of html-webpack-plugin, by default the assets will be injected into every file. This is configurable.
+
+This example assumes \`bootstrap\` is installed in the app. It:
+
+1. copies \`node_modules/bootstrap/dist/css/bootstrap.min.css\` to \`<output path>/vendor/bootstrap/dist/css/bootstrap.min.css\`
+1. adds \`<link href="/public/vendor/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">\` to *only the \`about.html\` file*, before your chunks
+
+\`\`\`js
+new HtmlWebpackExternalsPlugin({
+  externals: [
+    {
+      module: 'bootstrap',
+      entry: 'dist/css/bootstrap.min.css',
+    },
+  ],
+  files: ['about.html'],
 })
 \`\`\`

package-lock.json

Inline diff not displayed. View the whole file

package.json

Show changes
@@ -1,6 +1,6 @@
 {
 	"name": "html-webpack-externals-plugin",
-	"version": "3.2.0",
+	"version": "3.3.0",
 	"description": "Webpack plugin that works alongside html-webpack-plugin to use pre-packaged vendor bundles.",
 	"keywords": [
 		"htmlwebpackplugin",
@@ -52,6 +52,6 @@
 	"dependencies": {
 		"ajv": "^5.2.2",
 		"copy-webpack-plugin": "^4.0.1",
-		"html-webpack-include-assets-plugin": "0.0.6"
+		"html-webpack-include-assets-plugin": "0.0.7"
 	}
 }

src/HtmlWebpackExternalsPlugin.js

Show changes
@@ -15,9 +15,21 @@ export default class HtmlWebpackExternalsPlugin {
 						properties: {
 							module: { type: 'string' },
 							entry: {
-								type: ['string', 'array'],
-								items: { type: 'string' },
+								type: ['string', 'array', 'object'],
+								items: {
+									type: ['string', 'object'],
+									properties: {
+										path: { type: 'string' },
+										type: { type: 'string', enum: ['js', 'css'] },
+									},
+									required: ['path', 'type'],
+								},
 								minItems: 1,
+								properties: {
+									path: { type: 'string' },
+									type: { type: 'string', enum: ['js', 'css'] },
+								},
+								required: ['path', 'type'],
 							},
 							global: { type: ['string', 'null'], default: null },
 							supplements: {
@@ -73,12 +85,15 @@ export default class HtmlWebpackExternalsPlugin {
 			const localEntries = []
 
 			const entries = (Array.isArray(entry) ? entry : [entry]).map(entry => {
-				if (HtmlWebpackExternalsPlugin.URL_ENTRY.test(entry)) {
+				if (typeof entry === 'string') {
+					entry = { path: entry, type: null }
+				}
+				if (HtmlWebpackExternalsPlugin.URL_ENTRY.test(entry.path)) {
 					return entry
 				}
-				const localEntry = \`${module}/${entry}\`
+				const localEntry = \`${module}/${entry.path}\`
 				localEntries.push(localEntry)
-				return localEntry
+				return { ...entry, path: localEntry }
 			})
 
 			if (append) {
@@ -129,9 +144,12 @@ export default class HtmlWebpackExternalsPlugin {
 					new HtmlWebpackIncludeAssetsPlugin({
 						assets: assets.map(
 							asset =>
-								HtmlWebpackExternalsPlugin.URL_ENTRY.test(asset)
+								HtmlWebpackExternalsPlugin.URL_ENTRY.test(asset.path)
 									? asset
-									: \`${publicPath}${this.outputPath}/${asset}\`
+									: {
+											...asset,
+											path: \`${publicPath}${this.outputPath}/${asset.path}\`,
+										}
 						),
 						append,
 						hash: this.hash,