diff --git a/index.js b/index.js index d96988bc..3bbdfdf1 100644 --- a/index.js +++ b/index.js @@ -517,6 +517,21 @@ class HtmlWebpackPlugin { return assets.js.length && assets.js.every((assetPath) => /\.hot-update\.js$/.test(assetPath)); } + /** + * Check the path is a absolute url path + * + * @param {string | undefined} path + */ + isAbsolutePath (path) { + if (typeof path === 'undefined' || path === '') return false; + // If the path start with '/' + if (path.indexOf('/') === 0) return true; + // If the path contain the '://' scheme + if (path.indexOf('://') !== -1) return true; + + return false; + } + /** * The htmlWebpackPluginAssets extracts the asset information of a webpack compilation * for all given entry names @@ -535,13 +550,13 @@ class HtmlWebpackPlugin { /** * @type {string} the configured public path to the asset root - * if a publicPath is set in the current webpack config use it otherwise + * if the absolute path publicPath is set in the current webpack config use it otherwise * fallback to a realtive path */ - let publicPath = typeof compilation.options.output.publicPath !== 'undefined' - // If a hard coded public path exists use it + let publicPath = this.isAbsolutePath(compilation.options.output.publicPath) + // If a absolute path is set in the publicPath use it ? compilation.mainTemplate.getPublicPath({hash: compilationHash}) - // If no public path was set get a relative url path + // If publicPath was a relative path get the realtive path : path.relative(path.resolve(compilation.options.output.path, path.dirname(childCompilationOutputName)), compilation.options.output.path) .split(path.sep).join('/'); diff --git a/spec/basic.spec.js b/spec/basic.spec.js index 17df8a6b..7bd3492c 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -485,6 +485,51 @@ describe('HtmlWebpackPlugin', () => { }, [' { + testHtmlPlugin({ + mode: 'production', + entry: path.join(__dirname, 'fixtures/theme.js'), + output: { + path: OUTPUT_DIR, + filename: 'index_bundle.js', + publicPath: 'some/' + }, + module: { + rules: [ + { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] } + ] + }, + plugins: [ + new HtmlWebpackPlugin({hash: true}), + new MiniCssExtractPlugin({filename: 'styles.css'}) + ] + }, [' { + testHtmlPlugin({ + mode: 'production', + entry: path.join(__dirname, 'fixtures/theme.js'), + output: { + path: OUTPUT_DIR, + filename: 'index_bundle.js', + publicPath: 'some/' + }, + module: { + rules: [ + { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] } + ] + }, + plugins: [ + new HtmlWebpackPlugin({ + hash: true, + filename: path.resolve(OUTPUT_DIR, 'subfolder', 'test.html') + }), + new MiniCssExtractPlugin({filename: 'styles.css'}) + ] + }, [' { testHtmlPlugin({ mode: 'production', @@ -550,6 +595,19 @@ describe('HtmlWebpackPlugin', () => { }, [''], null, done); }); + it('prepends the webpack public path to relative path', done => { + testHtmlPlugin({ + mode: 'production', + entry: path.join(__dirname, 'fixtures/index.js'), + output: { + path: OUTPUT_DIR, + filename: 'index_bundle.js', + publicPath: 'assets/' + }, + plugins: [new HtmlWebpackPlugin()] + }, ['