11const { resolve, join } = require ( 'path' ) ;
22const os = require ( 'os' ) ;
33const { existsSync, readFileSync, writeFileSync, mkdirSync } = 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' ) ;
@@ -16,8 +18,8 @@ function read(path) {
1618 return readFileSync ( resolve ( __dirname , path ) , 'utf-8' ) ;
1719}
1820
19- module . exports = async function ( config ) {
20- const { cwd, dest, isProd , src } = config ;
21+ module . exports = async function renderHTMLPlugin ( config ) {
22+ const { cwd, dest, src } = config ;
2123 const inProjectTemplatePath = resolve ( src , 'template.html' ) ;
2224 let template = defaultTemplate ;
2325 if ( existsSync ( inProjectTemplatePath ) ) {
@@ -33,14 +35,11 @@ module.exports = async function (config) {
3335 }
3436
3537 let content = read ( template ) ;
36- 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 ) ) {
38+ 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 ) ) {
3739 const headEnd = read ( '../../resources/head-end.ejs' ) ;
3840 const bodyEnd = read ( '../../resources/body-end.ejs' ) ;
3941 content = content
40- . replace (
41- / < % [ = ] ? \s + p r e a c t \. t i t l e \s + % > / ,
42- '<%= htmlWebpackPlugin.options.title %>'
43- )
42+ . replace ( / < % [ = ] ? \s + p r e a c t \. t i t l e \s + % > / , '<%= cli.title %>' )
4443 . replace ( / < % \s + p r e a c t \. h e a d E n d \s + % > / , headEnd )
4544 . replace ( / < % \s + p r e a c t \. b o d y E n d \s + % > / , bodyEnd ) ;
4645
@@ -55,53 +54,70 @@ module.exports = async function (config) {
5554 }
5655
5756 const htmlWebpackConfig = values => {
58- const { url, title, ...routeData } = values ;
57+ let { url, title, ...routeData } = values ;
58+
59+ title =
60+ title ||
61+ config . title ||
62+ config . manifest . name ||
63+ config . manifest . short_name ||
64+ ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
65+ 'Preact App' ;
66+
5967 // Do not create a folder if the url is for a specific file.
6068 const filename = url . endsWith ( '.html' )
6169 ? resolve ( dest , url . substring ( 1 ) )
6270 : resolve ( dest , url . substring ( 1 ) , 'index.html' ) ;
63- return Object . assign ( values , {
71+
72+ return {
73+ title,
6474 filename,
6575 template : `!!${ require . resolve ( 'ejs-loader' ) } ?esModule=false!${ template } ` ,
66- minify : isProd && {
67- collapseWhitespace : true ,
68- removeScriptTypeAttributes : true ,
69- removeRedundantAttributes : true ,
70- removeStyleLinkTypeAttributes : true ,
71- removeComments : true ,
76+ templateParameters : ( compilation , assets , assetTags , options ) => {
77+ let entrypoints = { } ;
78+ compilation . entrypoints . forEach ( ( entrypoint , name ) => {
79+ let entryFiles = entrypoint . getFiles ( ) ;
80+ entrypoints [ name ] =
81+ assets . publicPath +
82+ entryFiles . find ( file => / \. ( m ? j s ) ( \? | $ ) / . test ( file ) ) ;
83+ } ) ;
84+
85+ let loadManifest = compilation . assets [ 'push-manifest.json' ]
86+ ? JSON . parse ( compilation . assets [ 'push-manifest.json' ] . source ( ) )
87+ : createLoadManifest (
88+ compilation . assets ,
89+ config . esm ,
90+ compilation . namedChunkGroups
91+ ) ;
92+
93+ return {
94+ cli : {
95+ title,
96+ url,
97+ manifest : config . manifest ,
98+ inlineCss : config [ 'inline-css' ] ,
99+ preload : config . preload ,
100+ config,
101+ preRenderData : values ,
102+ CLI_DATA : { preRenderData : { url, ...routeData } } ,
103+ ssr : config . prerender ? prerender ( { cwd, dest, src } , values ) : '' ,
104+ loadManifest,
105+ entrypoints,
106+ } ,
107+ htmlWebpackPlugin : {
108+ tags : assetTags ,
109+ files : assets ,
110+ options,
111+ } ,
112+ } ;
72113 } ,
114+ inject : true ,
115+ scriptLoading : 'defer' ,
73116 favicon : existsSync ( resolve ( src , 'assets/favicon.ico' ) )
74117 ? 'assets/favicon.ico'
75118 : '' ,
76- inject : true ,
77- compile : true ,
78- inlineCss : config [ 'inline-css' ] ,
79- preload : config . preload ,
80- manifest : config . manifest ,
81- title :
82- title ||
83- config . title ||
84- config . manifest . name ||
85- config . manifest . short_name ||
86- ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
87- 'Preact App' ,
88119 excludeAssets : [ / ( b u n d l e | p o l y f i l l s ) ( \. .* ) ? \. j s $ / ] ,
89- createLoadManifest : ( assets , namedChunkGroups ) => {
90- if ( assets [ 'push-manifest.json' ] ) {
91- return JSON . parse ( assets [ 'push-manifest.json' ] . source ( ) ) ;
92- }
93- return createLoadManifest ( assets , config . esm , namedChunkGroups ) ;
94- } ,
95- config,
96- url,
97- ssr ( ) {
98- return config . prerender && url !== PREACT_FALLBACK_URL
99- ? prerender ( { cwd, dest, src } , values )
100- : '' ;
101- } ,
102- scriptLoading : 'defer' ,
103- CLI_DATA : { preRenderData : { url, ...routeData } } ,
104- } ) ;
120+ } ;
105121 } ;
106122
107123 let pages = [ { url : '/' } ] ;
@@ -157,7 +173,7 @@ module.exports = async function (config) {
157173 const resultPages = pages
158174 . map ( htmlWebpackConfig )
159175 . map ( conf => new HtmlWebpackPlugin ( conf ) )
160- . concat ( [ new HtmlWebpackExcludeAssetsPlugin ( ) ] ) ;
176+ . concat ( [ new HtmlWebpackSkipAssetsPlugin ( ) ] ) ;
161177
162178 return config . prerender
163179 ? resultPages . concat ( [
@@ -169,10 +185,9 @@ module.exports = async function (config) {
169185// Adds a preact_prerender_data in every folder so that the data could be fetched separately.
170186class PrerenderDataExtractPlugin {
171187 constructor ( page ) {
172- const cliData = page . CLI_DATA || { } ;
173- const { url } = cliData . preRenderData || { } ;
188+ const url = page . url ;
174189 this . location_ = url . endsWith ( '/' ) ? url : url + '/' ;
175- this . data_ = JSON . stringify ( cliData . preRenderData || { } ) ;
190+ this . data_ = JSON . stringify ( page || { } ) ;
176191 }
177192 apply ( compiler ) {
178193 compiler . hooks . emit . tap ( 'PrerenderDataExtractPlugin' , compilation => {
0 commit comments