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' ) ;
@@ -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
@@ -54,53 +53,69 @@ module.exports = async function (config) {
5453 }
5554
5655 const htmlWebpackConfig = values => {
57- const { url, title, ...routeData } = values ;
56+ let { url, title, ...routeData } = values ;
57+
58+ title =
59+ title ||
60+ config . title ||
61+ config . manifest . name ||
62+ config . manifest . short_name ||
63+ ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
64+ 'Preact App' ;
65+
5866 // Do not create a folder if the url is for a specific file.
5967 const filename = url . endsWith ( '.html' )
6068 ? resolve ( dest , url . substring ( 1 ) )
6169 : resolve ( dest , url . substring ( 1 ) , 'index.html' ) ;
62- return Object . assign ( values , {
70+
71+ return {
72+ title,
6373 filename,
6474 template : `!!${ require . resolve ( 'ejs-loader' ) } ?esModule=false!${ template } ` ,
65- minify : isProd && {
66- collapseWhitespace : true ,
67- removeScriptTypeAttributes : true ,
68- removeRedundantAttributes : true ,
69- removeStyleLinkTypeAttributes : true ,
70- removeComments : true ,
75+ templateParameters : ( compilation , assets , assetTags , options ) => {
76+ let entrypoints = { } ;
77+ compilation . entrypoints . forEach ( ( entrypoint , name ) => {
78+ let entryFiles = entrypoint . getFiles ( ) ;
79+ entrypoints [ name ] =
80+ assets . publicPath +
81+ entryFiles . find ( file => / \. ( m ? j s ) ( \? | $ ) / . test ( file ) ) ;
82+ } ) ;
83+
84+ let loadManifest = compilation . assets [ 'push-manifest.json' ]
85+ ? JSON . parse ( compilation . assets [ 'push-manifest.json' ] . source ( ) )
86+ : createLoadManifest (
87+ compilation . assets ,
88+ compilation . namedChunkGroups
89+ ) ;
90+
91+ return {
92+ cli : {
93+ title,
94+ url,
95+ manifest : config . manifest ,
96+ inlineCss : config [ 'inline-css' ] ,
97+ preload : config . preload ,
98+ config,
99+ preRenderData : values ,
100+ CLI_DATA : { preRenderData : { url, ...routeData } } ,
101+ ssr : config . prerender ? prerender ( { cwd, dest, src } , values ) : '' ,
102+ loadManifest,
103+ entrypoints,
104+ } ,
105+ htmlWebpackPlugin : {
106+ tags : assetTags ,
107+ files : assets ,
108+ options,
109+ } ,
110+ } ;
71111 } ,
112+ inject : true ,
113+ scriptLoading : 'defer' ,
72114 favicon : existsSync ( resolve ( src , 'assets/favicon.ico' ) )
73115 ? 'assets/favicon.ico'
74116 : '' ,
75- inject : true ,
76- compile : true ,
77- inlineCss : config [ 'inline-css' ] ,
78- preload : config . preload ,
79- manifest : config . manifest ,
80- title :
81- title ||
82- config . title ||
83- config . manifest . name ||
84- config . manifest . short_name ||
85- ( config . pkg . name || '' ) . replace ( / ^ @ [ a - z ] \/ / , '' ) ||
86- 'Preact App' ,
87117 excludeAssets : [ / ( b u n d l e | p o l y f i l l s ) ( \. .* ) ? \. j s $ / ] ,
88- createLoadManifest : ( assets , namedChunkGroups ) => {
89- if ( assets [ 'push-manifest.json' ] ) {
90- return JSON . parse ( assets [ 'push-manifest.json' ] . source ( ) ) ;
91- }
92- return createLoadManifest ( assets , namedChunkGroups ) ;
93- } ,
94- config,
95- url,
96- ssr ( ) {
97- return config . prerender && url !== PREACT_FALLBACK_URL
98- ? prerender ( { cwd, dest, src } , values )
99- : '' ;
100- } ,
101- scriptLoading : 'defer' ,
102- CLI_DATA : { preRenderData : { url, ...routeData } } ,
103- } ) ;
118+ } ;
104119 } ;
105120
106121 let pages = [ { url : '/' } ] ;
@@ -151,7 +166,7 @@ module.exports = async function (config) {
151166 const resultPages = pages
152167 . map ( htmlWebpackConfig )
153168 . map ( conf => new HtmlWebpackPlugin ( conf ) )
154- . concat ( [ new HtmlWebpackExcludeAssetsPlugin ( ) ] ) ;
169+ . concat ( [ new HtmlWebpackSkipAssetsPlugin ( ) ] ) ;
155170
156171 return config . prerender
157172 ? resultPages . concat ( [
@@ -163,10 +178,9 @@ module.exports = async function (config) {
163178// Adds a preact_prerender_data in every folder so that the data could be fetched separately.
164179class PrerenderDataExtractPlugin {
165180 constructor ( page ) {
166- const cliData = page . CLI_DATA || { } ;
167- const { url } = cliData . preRenderData || { } ;
181+ const url = page . url ;
168182 this . location_ = url . endsWith ( '/' ) ? url : url + '/' ;
169- this . data_ = JSON . stringify ( cliData . preRenderData || { } ) ;
183+ this . data_ = JSON . stringify ( page || { } ) ;
170184 }
171185 apply ( compiler ) {
172186 compiler . hooks . emit . tap ( 'PrerenderDataExtractPlugin' , compilation => {
0 commit comments