Skip to content

Commit dbbdd81

Browse files
Wind4jantimon
authored andcommittedOct 3, 2018
feat: Add publicPath support relative path
1 parent f4bccb7 commit dbbdd81

File tree

2 files changed

+159
-6
lines changed

2 files changed

+159
-6
lines changed
 

‎index.js

+19-4
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,21 @@ class HtmlWebpackPlugin {
517517
return assets.js.length && assets.js.every((assetPath) => /\.hot-update\.js$/.test(assetPath));
518518
}
519519

520+
/**
521+
* Check the path is a absolute url path
522+
*
523+
* @param {string | undefined} path
524+
*/
525+
isAbsolutePath (path) {
526+
if (typeof path === 'undefined' || path === '') return false;
527+
// If the path start with '/'
528+
if (path.indexOf('/') === 0) return true;
529+
// If the path contain the '://' scheme
530+
if (path.indexOf('://') !== -1) return true;
531+
532+
return false;
533+
}
534+
520535
/**
521536
* The htmlWebpackPluginAssets extracts the asset information of a webpack compilation
522537
* for all given entry names
@@ -535,13 +550,13 @@ class HtmlWebpackPlugin {
535550

536551
/**
537552
* @type {string} the configured public path to the asset root
538-
* if a publicPath is set in the current webpack config use it otherwise
553+
* if the absolute path publicPath is set in the current webpack config use it otherwise
539554
* fallback to a realtive path
540555
*/
541-
let publicPath = typeof compilation.options.output.publicPath !== 'undefined'
542-
// If a hard coded public path exists use it
556+
let publicPath = this.isAbsolutePath(compilation.options.output.publicPath)
557+
// If a absolute path is set in the publicPath use it
543558
? compilation.mainTemplate.getPublicPath({hash: compilationHash})
544-
// If no public path was set get a relative url path
559+
// If publicPath was a relative path get the realtive path
545560
: path.relative(path.resolve(compilation.options.output.path, path.dirname(childCompilationOutputName)), compilation.options.output.path)
546561
.split(path.sep).join('/');
547562

‎spec/basic.spec.js

+140-2
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,51 @@ describe('HtmlWebpackPlugin', () => {
485485
}, ['<link href="styles.css?%hash%"'], null, done);
486486
});
487487

488+
it('should allow to add cache hashes to with the css assets', done => {
489+
testHtmlPlugin({
490+
mode: 'production',
491+
entry: path.join(__dirname, 'fixtures/theme.js'),
492+
output: {
493+
path: OUTPUT_DIR,
494+
filename: 'index_bundle.js',
495+
publicPath: 'some/'
496+
},
497+
module: {
498+
rules: [
499+
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }
500+
]
501+
},
502+
plugins: [
503+
new HtmlWebpackPlugin({hash: true}),
504+
new MiniCssExtractPlugin({filename: 'styles.css'})
505+
]
506+
}, ['<link href="styles.css?%hash%"'], null, done);
507+
});
508+
509+
it('should allow to add cache hashes to with the css assets', done => {
510+
testHtmlPlugin({
511+
mode: 'production',
512+
entry: path.join(__dirname, 'fixtures/theme.js'),
513+
output: {
514+
path: OUTPUT_DIR,
515+
filename: 'index_bundle.js',
516+
publicPath: 'some/'
517+
},
518+
module: {
519+
rules: [
520+
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }
521+
]
522+
},
523+
plugins: [
524+
new HtmlWebpackPlugin({
525+
hash: true,
526+
filename: path.resolve(OUTPUT_DIR, 'subfolder', 'test.html')
527+
}),
528+
new MiniCssExtractPlugin({filename: 'styles.css'})
529+
]
530+
}, ['<link href="../styles.css?%hash%"'], path.join('subfolder', 'test.html'), done);
531+
});
532+
488533
it('should inject css files when using the extract text plugin', done => {
489534
testHtmlPlugin({
490535
mode: 'production',
@@ -550,6 +595,19 @@ describe('HtmlWebpackPlugin', () => {
550595
}, ['<link href="styles.css" rel="stylesheet"/>'], null, done);
551596
});
552597

598+
it('prepends the webpack public path to relative path', done => {
599+
testHtmlPlugin({
600+
mode: 'production',
601+
entry: path.join(__dirname, 'fixtures/index.js'),
602+
output: {
603+
path: OUTPUT_DIR,
604+
filename: 'index_bundle.js',
605+
publicPath: 'assets/'
606+
},
607+
plugins: [new HtmlWebpackPlugin()]
608+
}, ['<script src="index_bundle.js"'], null, done);
609+
});
610+
553611
it('prepends the webpack public path to script src', done => {
554612
testHtmlPlugin({
555613
mode: 'production',
@@ -575,7 +633,35 @@ describe('HtmlWebpackPlugin', () => {
575633
}, ['<script src="assets/index_bundle.js"'], null, done);
576634
});
577635

578-
it('handles subdirectories in the webpack output bundles along with a public path', done => {
636+
it('handles subdirectories in the webpack output bundles along with a relative path', done => {
637+
testHtmlPlugin({
638+
mode: 'production',
639+
entry: path.join(__dirname, 'fixtures/index.js'),
640+
output: {
641+
path: OUTPUT_DIR,
642+
filename: 'assets/index_bundle.js',
643+
publicPath: 'some/'
644+
},
645+
plugins: [new HtmlWebpackPlugin()]
646+
}, ['<script src="assets/index_bundle.js"'], null, done);
647+
});
648+
649+
it('handles subdirectories in the webpack output bundles along with a relative path', done => {
650+
testHtmlPlugin({
651+
mode: 'production',
652+
entry: path.join(__dirname, 'fixtures/index.js'),
653+
output: {
654+
path: OUTPUT_DIR,
655+
filename: 'assets/index_bundle.js',
656+
publicPath: 'some/'
657+
},
658+
plugins: [new HtmlWebpackPlugin({
659+
filename: path.resolve(OUTPUT_DIR, 'subfolder', 'test.html')
660+
})]
661+
}, ['<script src="../assets/index_bundle.js"'], path.join('subfolder', 'test.html'), done);
662+
});
663+
664+
it('handles subdirectories in the webpack output bundles along with a absolute path', done => {
579665
testHtmlPlugin({
580666
mode: 'production',
581667
entry: path.join(__dirname, 'fixtures/index.js'),
@@ -1433,7 +1519,42 @@ describe('HtmlWebpackPlugin', () => {
14331519
}, [/<link rel="shortcut icon" href="\/some\/+[^"]+\.ico">/], null, done);
14341520
});
14351521

1436-
it('adds a favicon with a publichPath set to [hash]/ and replaces the hash', done => {
1522+
it('adds a favicon with publicPath set to some/', done => {
1523+
testHtmlPlugin({
1524+
mode: 'production',
1525+
entry: path.join(__dirname, 'fixtures/index.js'),
1526+
output: {
1527+
path: OUTPUT_DIR,
1528+
publicPath: 'some/',
1529+
filename: 'index_bundle.js'
1530+
},
1531+
plugins: [
1532+
new HtmlWebpackPlugin({
1533+
favicon: path.join(__dirname, 'fixtures/favicon.ico')
1534+
})
1535+
]
1536+
}, [/<link rel="shortcut icon" href="[^"]+\.ico">/], null, done);
1537+
});
1538+
1539+
it('adds a favicon with publicPath set to some/', done => {
1540+
testHtmlPlugin({
1541+
mode: 'production',
1542+
entry: path.join(__dirname, 'fixtures/index.js'),
1543+
output: {
1544+
path: OUTPUT_DIR,
1545+
publicPath: 'some/',
1546+
filename: 'index_bundle.js'
1547+
},
1548+
plugins: [
1549+
new HtmlWebpackPlugin({
1550+
favicon: path.join(__dirname, 'fixtures/favicon.ico'),
1551+
filename: path.resolve(OUTPUT_DIR, 'subfolder', 'test.html')
1552+
})
1553+
]
1554+
}, [/<link rel="shortcut icon" href="\.\.\/[^"]+\.ico">/], path.join('subfolder', 'test.html'), done);
1555+
});
1556+
1557+
it('adds a favicon with a publichPath set to /[hash]/ and replaces the hash', done => {
14371558
testHtmlPlugin({
14381559
mode: 'production',
14391560
entry: path.join(__dirname, 'fixtures/index.js'),
@@ -1450,6 +1571,23 @@ describe('HtmlWebpackPlugin', () => {
14501571
}, [/<link rel="shortcut icon" href="\/[a-z0-9]{20}\/favicon\.ico">/], null, done);
14511572
});
14521573

1574+
it('adds a favicon with a publichPath set to [hash]/ and replaces the hash', done => {
1575+
testHtmlPlugin({
1576+
mode: 'production',
1577+
entry: path.join(__dirname, 'fixtures/index.js'),
1578+
output: {
1579+
path: OUTPUT_DIR,
1580+
publicPath: '[hash]/',
1581+
filename: 'index_bundle.js'
1582+
},
1583+
plugins: [
1584+
new HtmlWebpackPlugin({
1585+
favicon: path.join(__dirname, 'fixtures/favicon.ico')
1586+
})
1587+
]
1588+
}, [/<link rel="shortcut icon" href="favicon\.ico">/], null, done);
1589+
});
1590+
14531591
it('adds a favicon with inject enabled', done => {
14541592
testHtmlPlugin({
14551593
mode: 'production',

0 commit comments

Comments
 (0)
Please sign in to comment.