11const { resolve, join } = require ( 'path' ) ;
22const os = require ( 'os' ) ;
33const { existsSync, mkdtempSync, readFileSync, writeFileSync } = require ( 'fs' ) ;
4- const HtmlWebpackExcludeAssetsPlugin = require ( 'html-webpack-exclude-assets-plugin' ) ;
4+ const {
5+ HtmlWebpackSkipAssetsPlugin,
6+ } = require ( 'html-webpack-skip-assets-plugin' ) ;
57const HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
68const prerender = require ( './prerender' ) ;
79const createLoadManifest = require ( './create-load-manifest' ) ;
@@ -15,8 +17,8 @@ function read(path) {
1517 return readFileSync ( resolve ( __dirname , path ) , 'utf-8' ) ;
1618}
1719
18- module . exports = async function ( config ) {
19- const { cwd, dest, isProd , src } = config ;
20+ module . exports = async function renderHTMLPlugin ( config ) {
21+ const { cwd, dest, src } = config ;
2022 const inProjectTemplatePath = resolve ( src , 'template.html' ) ;
2123 let template = defaultTemplate ;
2224 if ( existsSync ( inProjectTemplatePath ) ) {
@@ -32,14 +34,11 @@ module.exports = async function (config) {
3234 }
3335
3436 let content = read ( template ) ;
35- if ( / p r e a c t \. h e a d E n d | p r e a c t \. b o d y E n d / . test ( content ) ) {
37+ if ( / p r e a c t \. ( t i t l e | h e a d E n d | b o d y E n d ) / . test ( content ) ) {
3638 const headEnd = read ( '../../resources/head-end.ejs' ) ;
3739 const bodyEnd = read ( '../../resources/body-end.ejs' ) ;
3840 content = content
39- . replace (
40- / < % [ = ] ? \s + p r e a c t \. t i t l e \s + % > / ,
41- '<%= htmlWebpackPlugin.options.title %>'
42- )
41+ . replace ( / < % [ = ] ? \s + p r e a c t \. t i t l e \s + % > / , '<%= cli.title %>' )
4342 . replace ( / < % \s + p r e a c t \. h e a d E n d \s + % > / , headEnd )
4443 . replace ( / < % \s + p r e a c t \. b o d y E n d \s + % > / , bodyEnd ) ;
4544
@@ -51,53 +50,72 @@ module.exports = async function (config) {
5150 }
5251
5352 const htmlWebpackConfig = values => {
54- const { url, title, ...routeData } = values ;
53+ let { url, title, ...routeData } = values ;
54+
55+ title =
56+ title ||
57+ config . title ||
58+ config . manifest . name ||
59+ config . manifest . short_name ||
60+ ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
61+ 'Preact App' ;
62+
5563 // Do not create a folder if the url is for a specific file.
5664 const filename = url . endsWith ( '.html' )
5765 ? resolve ( dest , url . substring ( 1 ) )
5866 : resolve ( dest , url . substring ( 1 ) , 'index.html' ) ;
59- return Object . assign ( values , {
67+
68+ return {
69+ title,
6070 filename,
6171 template : `!!${ require . resolve ( 'ejs-loader' ) } ?esModule=false!${ template } ` ,
62- minify : isProd && {
63- collapseWhitespace : true ,
64- removeScriptTypeAttributes : true ,
65- removeRedundantAttributes : true ,
66- removeStyleLinkTypeAttributes : true ,
67- removeComments : true ,
72+ templateParameters : ( compilation , assets , assetTags , options ) => {
73+ let entrypoints = { } ;
74+ compilation . entrypoints . forEach ( ( entrypoint , name ) => {
75+ let entryFiles = entrypoint . getFiles ( ) ;
76+ entrypoints [ name ] =
77+ assets . publicPath +
78+ entryFiles . find ( file => / \. ( m ? j s ) ( \? | $ ) / . test ( file ) ) ;
79+ } ) ;
80+
81+ let loadManifest = compilation . assets [ 'push-manifest.json' ]
82+ ? JSON . parse ( compilation . assets [ 'push-manifest.json' ] . source ( ) )
83+ : createLoadManifest (
84+ compilation . assets ,
85+ compilation . namedChunkGroups ,
86+ config . isProd
87+ ) ;
88+
89+ return {
90+ cli : {
91+ title,
92+ url,
93+ manifest : config . manifest ,
94+ inlineCss : config [ 'inline-css' ] ,
95+ preload : config . preload ,
96+ config,
97+ preRenderData : values ,
98+ CLI_DATA : { preRenderData : { url, ...routeData } } ,
99+ ssr : config . prerender ? prerender ( { cwd, dest, src } , values ) : '' ,
100+ loadManifest,
101+ entrypoints,
102+ } ,
103+ htmlWebpackPlugin : {
104+ tags : assetTags ,
105+ files : assets ,
106+ options,
107+ } ,
108+ } ;
68109 } ,
110+ inject : true ,
69111 favicon : existsSync ( resolve ( src , 'assets/favicon.ico' ) )
70112 ? 'assets/favicon.ico'
71113 : '' ,
72- inject : true ,
73- compile : true ,
74- inlineCss : config [ 'inline-css' ] ,
75- preload : config . preload ,
76- manifest : config . manifest ,
77- title :
78- title ||
79- config . title ||
80- config . manifest . name ||
81- config . manifest . short_name ||
82- ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
83- 'Preact App' ,
114+ manifest : existsSync ( resolve ( src , 'manifest.json' ) )
115+ ? 'manifest.json'
116+ : '' ,
84117 excludeAssets : [ / ( b u n d l e | p o l y f i l l s ) ( \. .* ) ? \. j s $ / ] ,
85- createLoadManifest : ( assets , namedChunkGroups ) => {
86- if ( assets [ 'push-manifest.json' ] ) {
87- return JSON . parse ( assets [ 'push-manifest.json' ] . source ( ) ) ;
88- }
89- return createLoadManifest ( assets , namedChunkGroups , config . isProd ) ;
90- } ,
91- config,
92- url,
93- ssr ( ) {
94- return config . prerender && url !== PREACT_FALLBACK_URL
95- ? prerender ( { cwd, dest, src } , values )
96- : '' ;
97- } ,
98- scriptLoading : 'defer' ,
99- CLI_DATA : { preRenderData : { url, ...routeData } } ,
100- } ) ;
118+ } ;
101119 } ;
102120
103121 let pages = [ { url : '/' } ] ;
@@ -148,7 +166,7 @@ module.exports = async function (config) {
148166 const resultPages = pages
149167 . map ( htmlWebpackConfig )
150168 . map ( conf => new HtmlWebpackPlugin ( conf ) )
151- . concat ( [ new HtmlWebpackExcludeAssetsPlugin ( ) ] ) ;
169+ . concat ( [ new HtmlWebpackSkipAssetsPlugin ( ) ] ) ;
152170
153171 return config . prerender
154172 ? resultPages . concat ( [
@@ -160,10 +178,9 @@ module.exports = async function (config) {
160178// Adds a preact_prerender_data in every folder so that the data could be fetched separately.
161179class PrerenderDataExtractPlugin {
162180 constructor ( page ) {
163- const cliData = page . CLI_DATA || { } ;
164- const { url } = cliData . preRenderData || { } ;
181+ const url = page . url ;
165182 this . location_ = url . endsWith ( '/' ) ? url : url + '/' ;
166- this . data_ = JSON . stringify ( cliData . preRenderData || { } ) ;
183+ this . data_ = JSON . stringify ( page || { } ) ;
167184 }
168185 apply ( compiler ) {
169186 compiler . hooks . emit . tap ( 'PrerenderDataExtractPlugin' , compilation => {
0 commit comments