From 047464ba74a85f2e385d621b7806a0d4d8145ec1 Mon Sep 17 00:00:00 2001 From: chencheng Date: Tue, 18 Sep 2018 11:27:47 +0800 Subject: [PATCH 1/4] feat: support config scripts, headScripts, metas and links --- packages/umi-plugin-react/src/index.js | 6 ++++++ .../umi-plugin-react/src/plugins/headScripts.js | 11 +++++++++++ packages/umi-plugin-react/src/plugins/links.js | 11 +++++++++++ packages/umi-plugin-react/src/plugins/metas.js | 11 +++++++++++ .../src/plugins/mobile/fastClick.js | 1 - .../umi-plugin-react/src/plugins/mobile/hd.js | 1 - packages/umi-plugin-react/src/plugins/scripts.js | 11 +++++++++++ packages/umi-plugin-react/test/normal.e2e.js | 16 ++++++++++++++++ packages/umi-plugin-react/test/normal/.umirc.js | 8 ++++++++ .../test/normal/public/script2.js | 1 + 10 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 packages/umi-plugin-react/src/plugins/headScripts.js create mode 100644 packages/umi-plugin-react/src/plugins/links.js create mode 100644 packages/umi-plugin-react/src/plugins/metas.js delete mode 100644 packages/umi-plugin-react/src/plugins/mobile/fastClick.js delete mode 100644 packages/umi-plugin-react/src/plugins/mobile/hd.js create mode 100644 packages/umi-plugin-react/src/plugins/scripts.js create mode 100644 packages/umi-plugin-react/test/normal/public/script2.js diff --git a/packages/umi-plugin-react/src/index.js b/packages/umi-plugin-react/src/index.js index bf75aed6a8c7..833bb67cb114 100644 --- a/packages/umi-plugin-react/src/index.js +++ b/packages/umi-plugin-react/src/index.js @@ -47,6 +47,12 @@ export default function(api, option) { hardSource: () => require('./plugins/hardSource').default, pwa: () => require('./plugins/pwa').default, + // html tags + scripts: () => require('./plugins/scripts').default, + headScripts: () => require('./plugins/headScripts').default, + links: () => require('./plugins/links').default, + metas: () => require('./plugins/metas').default, + // misc dva: () => require('./plugins/dva').default, locale: () => require('./plugins/locale').default, diff --git a/packages/umi-plugin-react/src/plugins/headScripts.js b/packages/umi-plugin-react/src/plugins/headScripts.js new file mode 100644 index 000000000000..d715b67b3028 --- /dev/null +++ b/packages/umi-plugin-react/src/plugins/headScripts.js @@ -0,0 +1,11 @@ +export default function(api, option) { + api.onOptionChange(newOption => { + option = newOption; + api.rebuildHTML(); + api.refreshBrowser(); + }); + + api.addHTMLHeadScript(() => { + return option; + }); +} diff --git a/packages/umi-plugin-react/src/plugins/links.js b/packages/umi-plugin-react/src/plugins/links.js new file mode 100644 index 000000000000..72a302562f02 --- /dev/null +++ b/packages/umi-plugin-react/src/plugins/links.js @@ -0,0 +1,11 @@ +export default function(api, option) { + api.onOptionChange(newOption => { + option = newOption; + api.rebuildHTML(); + api.refreshBrowser(); + }); + + api.addHTMLLink(() => { + return option; + }); +} diff --git a/packages/umi-plugin-react/src/plugins/metas.js b/packages/umi-plugin-react/src/plugins/metas.js new file mode 100644 index 000000000000..866a7a916ac8 --- /dev/null +++ b/packages/umi-plugin-react/src/plugins/metas.js @@ -0,0 +1,11 @@ +export default function(api, option) { + api.onOptionChange(newOption => { + option = newOption; + api.rebuildHTML(); + api.refreshBrowser(); + }); + + api.addHTMLMeta(() => { + return option; + }); +} diff --git a/packages/umi-plugin-react/src/plugins/mobile/fastClick.js b/packages/umi-plugin-react/src/plugins/mobile/fastClick.js deleted file mode 100644 index 157c146d86b5..000000000000 --- a/packages/umi-plugin-react/src/plugins/mobile/fastClick.js +++ /dev/null @@ -1 +0,0 @@ -export default from '../fastClick'; diff --git a/packages/umi-plugin-react/src/plugins/mobile/hd.js b/packages/umi-plugin-react/src/plugins/mobile/hd.js deleted file mode 100644 index d4b2ce49bf7e..000000000000 --- a/packages/umi-plugin-react/src/plugins/mobile/hd.js +++ /dev/null @@ -1 +0,0 @@ -export default from '../hd'; diff --git a/packages/umi-plugin-react/src/plugins/scripts.js b/packages/umi-plugin-react/src/plugins/scripts.js new file mode 100644 index 000000000000..abfdf7da2442 --- /dev/null +++ b/packages/umi-plugin-react/src/plugins/scripts.js @@ -0,0 +1,11 @@ +export default function(api, option) { + api.onOptionChange(newOption => { + option = newOption; + api.rebuildHTML(); + api.refreshBrowser(); + }); + + api.addHTMLScript(() => { + return option; + }); +} diff --git a/packages/umi-plugin-react/test/normal.e2e.js b/packages/umi-plugin-react/test/normal.e2e.js index 798483555d1a..27c3e75716ca 100644 --- a/packages/umi-plugin-react/test/normal.e2e.js +++ b/packages/umi-plugin-react/test/normal.e2e.js @@ -43,6 +43,22 @@ describe('normal', () => { () => document.querySelector('title').innerHTML, ); expect(titleText).toEqual('默认标题'); + + // scripts + const scripts = await page.evaluate(() => window.scripts); + expect(scripts).toEqual(['headScript1', 'script1', 'script2']); + + // links + const link = await page.evaluate(() => + document.querySelector('#link1').getAttribute('foo'), + ); + expect(link).toEqual('bar'); + + // metas + const meta = await page.evaluate(() => + document.querySelector('#meta1').getAttribute('foo'), + ); + expect(meta).toEqual('bar'); }); it('a page', async () => { diff --git a/packages/umi-plugin-react/test/normal/.umirc.js b/packages/umi-plugin-react/test/normal/.umirc.js index bb1aac8c6238..62b997418689 100644 --- a/packages/umi-plugin-react/test/normal/.umirc.js +++ b/packages/umi-plugin-react/test/normal/.umirc.js @@ -27,6 +27,14 @@ export default { polyfills: [], antd: true, title: '默认标题', + + headScripts: [{ content: `window.scripts = ['headScript1'];` }], + scripts: [ + { content: `window.scripts.push('script1');` }, + { src: '/script2.js' }, + ], + metas: [{ id: 'meta1', foo: 'bar' }], + links: [{ id: 'link1', foo: 'bar' }], }, ], ], diff --git a/packages/umi-plugin-react/test/normal/public/script2.js b/packages/umi-plugin-react/test/normal/public/script2.js new file mode 100644 index 000000000000..15a2921b0235 --- /dev/null +++ b/packages/umi-plugin-react/test/normal/public/script2.js @@ -0,0 +1 @@ +window.scripts.push('script2'); From 7edd72b1a533d43a8df687408ca97760fa03df1d Mon Sep 17 00:00:00 2001 From: chencheng Date: Tue, 18 Sep 2018 14:14:31 +0800 Subject: [PATCH 2/4] feat: support chunks --- docs/plugin/develop.md | 4 ++++ docs/zh/plugin/develop.md | 4 ++++ packages/umi-build-dev/src/PluginAPI.js | 1 + .../umi-build-dev/src/html/HTMLGenerator.js | 24 +++++++++++++++---- .../src/plugins/commands/getHtmlGenerator.js | 5 ++++ packages/umi-plugin-react/src/index.js | 1 + .../umi-plugin-react/src/plugins/chunks.js | 11 +++++++++ 7 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 packages/umi-plugin-react/src/plugins/chunks.js diff --git a/docs/plugin/develop.md b/docs/plugin/develop.md index f68d60e77068..b765d802cfbf 100644 --- a/docs/plugin/develop.md +++ b/docs/plugin/develop.md @@ -402,6 +402,10 @@ api.addHTMLScript({ Add a script to the HTML head. +### modifyHTMLChunks + +Modify chunks in HTML. + ### modifyHTMLWithAST Modify the HTML, based on cheerio. diff --git a/docs/zh/plugin/develop.md b/docs/zh/plugin/develop.md index 92e816513600..f414ceee764e 100644 --- a/docs/zh/plugin/develop.md +++ b/docs/zh/plugin/develop.md @@ -403,6 +403,10 @@ api.addHTMLScript({ 在 HTML 头部添加脚本。 +### modifyHTMLChunks + +修改 chunks 。 + ### modifyHTMLWithAST 修改 HTML,基于 cheerio 。 diff --git a/packages/umi-build-dev/src/PluginAPI.js b/packages/umi-build-dev/src/PluginAPI.js index da472697c9fd..bed6f22b520b 100644 --- a/packages/umi-build-dev/src/PluginAPI.js +++ b/packages/umi-build-dev/src/PluginAPI.js @@ -93,6 +93,7 @@ export default class PluginAPI { 'addHTMLScript', 'addHTMLStyle', 'addHTMLHeadScript', + 'modifyHTMLChunks', 'onGenerateFiles', 'onHTMLRebuild', 'modifyDefaultConfig', diff --git a/packages/umi-build-dev/src/html/HTMLGenerator.js b/packages/umi-build-dev/src/html/HTMLGenerator.js index 51c459b4e376..3cf8fc229722 100644 --- a/packages/umi-build-dev/src/html/HTMLGenerator.js +++ b/packages/umi-build-dev/src/html/HTMLGenerator.js @@ -246,6 +246,9 @@ export default class HTMLGenerator { let scripts = []; let styles = []; let headScripts = []; + let chunks = ['umi']; + + if (this.modifyChunks) chunks = this.modifyChunks(chunks); let routerBaseStr = JSON.stringify(this.config.base || '/'); const publicPath = this.publicPath || '/'; @@ -273,8 +276,14 @@ export default class HTMLGenerator { ...(setPublicPath ? [`window.publicPath = ${publicPathStr};`] : []), ].join('\n'), }); - scripts.push({ - src: `<%= pathToPublicPath %>${this.getHashedFileName('umi.js')}`, + + chunks.forEach(chunk => { + const hashedFileName = this.getHashedFileName(`${chunk}.js`); + if (hashedFileName) { + scripts.push({ + src: `<%= pathToPublicPath %>${hashedFileName}`, + }); + } }); if (this.modifyMetas) metas = this.modifyMetas(metas); @@ -286,9 +295,14 @@ export default class HTMLGenerator { if (this.env === 'development' || this.chunksMap['umi.css']) { // umi.css should be the last one stylesheet - links.push({ - rel: 'stylesheet', - href: `<%= pathToPublicPath %>${this.getHashedFileName('umi.css')}`, + chunks.forEach(chunk => { + const hashedFileName = this.getHashedFileName(`${chunk}.css`); + if (hashedFileName) { + links.push({ + rel: 'stylesheet', + href: `<%= pathToPublicPath %>${hashedFileName}`, + }); + } }); } diff --git a/packages/umi-build-dev/src/plugins/commands/getHtmlGenerator.js b/packages/umi-build-dev/src/plugins/commands/getHtmlGenerator.js index 99a4e2a844c6..ca7a6f4d2551 100644 --- a/packages/umi-build-dev/src/plugins/commands/getHtmlGenerator.js +++ b/packages/umi-build-dev/src/plugins/commands/getHtmlGenerator.js @@ -22,6 +22,11 @@ export default (service, opts = {}) => { modifyPublicPathStr(str) { return str; }, + modifyChunks(memo) { + return service.applyPlugins('modifyHTMLChunks', { + initialValue: memo, + }); + }, modifyMetas(memo) { return service.applyPlugins('addHTMLMeta', { initialValue: memo, diff --git a/packages/umi-plugin-react/src/index.js b/packages/umi-plugin-react/src/index.js index 833bb67cb114..d6d37378c283 100644 --- a/packages/umi-plugin-react/src/index.js +++ b/packages/umi-plugin-react/src/index.js @@ -48,6 +48,7 @@ export default function(api, option) { pwa: () => require('./plugins/pwa').default, // html tags + chunks: () => require('./plugins/chunks').default, scripts: () => require('./plugins/scripts').default, headScripts: () => require('./plugins/headScripts').default, links: () => require('./plugins/links').default, diff --git a/packages/umi-plugin-react/src/plugins/chunks.js b/packages/umi-plugin-react/src/plugins/chunks.js new file mode 100644 index 000000000000..acb3dee8cdba --- /dev/null +++ b/packages/umi-plugin-react/src/plugins/chunks.js @@ -0,0 +1,11 @@ +export default function(api, option) { + api.onOptionChange(newOption => { + option = newOption; + api.rebuildHTML(); + api.refreshBrowser(); + }); + + api.modifyHTMLChunks(() => { + return option; + }); +} From e03a1b909118ae6d791e53f136ea56577fc4ca69 Mon Sep 17 00:00:00 2001 From: chencheng Date: Tue, 18 Sep 2018 14:36:14 +0800 Subject: [PATCH 3/4] <%= PUBLIC_PATH %> --- packages/umi-build-dev/src/html/HTMLGenerator.js | 4 +++- packages/umi-plugin-react/test/normal.e2e.js | 2 +- packages/umi-plugin-react/test/normal/.umirc.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/umi-build-dev/src/html/HTMLGenerator.js b/packages/umi-build-dev/src/html/HTMLGenerator.js index 3cf8fc229722..5b1b55158f99 100644 --- a/packages/umi-build-dev/src/html/HTMLGenerator.js +++ b/packages/umi-build-dev/src/html/HTMLGenerator.js @@ -336,7 +336,9 @@ ${scripts.length ? this.getScriptsContent(scripts) : ''} exportStatic && exportStatic.dynamicRoot ? relPathToPublicPath : publicPath; - html = html.replace(/<%= pathToPublicPath %>/g, pathToPublicPath); + html = html + .replace(/<%= pathToPublicPath %>/g, pathToPublicPath) + .replace(/<%= PUBLIC_PATH %>/g, pathToPublicPath); if (this.modifyHTML) { html = this.modifyHTML(html, { route }); diff --git a/packages/umi-plugin-react/test/normal.e2e.js b/packages/umi-plugin-react/test/normal.e2e.js index 27c3e75716ca..48819bba7d2a 100644 --- a/packages/umi-plugin-react/test/normal.e2e.js +++ b/packages/umi-plugin-react/test/normal.e2e.js @@ -58,7 +58,7 @@ describe('normal', () => { const meta = await page.evaluate(() => document.querySelector('#meta1').getAttribute('foo'), ); - expect(meta).toEqual('bar'); + expect(meta).toEqual('/bar'); }); it('a page', async () => { diff --git a/packages/umi-plugin-react/test/normal/.umirc.js b/packages/umi-plugin-react/test/normal/.umirc.js index 62b997418689..27521824cee2 100644 --- a/packages/umi-plugin-react/test/normal/.umirc.js +++ b/packages/umi-plugin-react/test/normal/.umirc.js @@ -33,7 +33,7 @@ export default { { content: `window.scripts.push('script1');` }, { src: '/script2.js' }, ], - metas: [{ id: 'meta1', foo: 'bar' }], + metas: [{ id: 'meta1', foo: '<%= PUBLIC_PATH %>bar' }], links: [{ id: 'link1', foo: 'bar' }], }, ], From 15eeba910c6093ee0f0d1e41bf8d1aae5a6c9773 Mon Sep 17 00:00:00 2001 From: chencheng Date: Tue, 18 Sep 2018 15:08:25 +0800 Subject: [PATCH 4/4] add example for chunks --- .../umi-build-dev/src/html/HTMLGenerator.js | 10 +++---- .../commands/dev/createRouteMiddleware.js | 6 +++- .../src/plugins/commands/dev/index.js | 1 + .../umi-plugin-react/test/chunks/.umirc.js | 30 +++++++++++++++++++ packages/umi-plugin-react/test/chunks/a.js | 1 + .../umi-plugin-react/test/chunks/package.json | 1 + .../test/chunks/pages/index.css | 4 +++ .../test/chunks/pages/index.js | 10 +++++++ .../test/chunks/pages/users.css | 4 +++ .../test/chunks/pages/users.js | 10 +++++++ 10 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 packages/umi-plugin-react/test/chunks/.umirc.js create mode 100644 packages/umi-plugin-react/test/chunks/a.js create mode 100644 packages/umi-plugin-react/test/chunks/package.json create mode 100644 packages/umi-plugin-react/test/chunks/pages/index.css create mode 100755 packages/umi-plugin-react/test/chunks/pages/index.js create mode 100644 packages/umi-plugin-react/test/chunks/pages/users.css create mode 100755 packages/umi-plugin-react/test/chunks/pages/users.js diff --git a/packages/umi-build-dev/src/html/HTMLGenerator.js b/packages/umi-build-dev/src/html/HTMLGenerator.js index 5b1b55158f99..cce831ede259 100644 --- a/packages/umi-build-dev/src/html/HTMLGenerator.js +++ b/packages/umi-build-dev/src/html/HTMLGenerator.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import { join, relative } from 'path'; +import { join, relative, extname } from 'path'; import { existsSync, readFileSync } from 'fs'; import isPlainObject from 'is-plain-object'; import ejs from 'ejs'; @@ -188,18 +188,16 @@ export default class HTMLGenerator { } getHashedFileName(filename) { - const isProduction = this.env === 'production'; - if (isProduction) { + // css is optional + if (extname(filename) === '.js') { assert( this.chunksMap[filename], `file ${filename} don't exists in chunksMap ${JSON.stringify( this.chunksMap, )}`, ); - return this.chunksMap[filename]; - } else { - return filename; } + return this.chunksMap[filename]; } getContent(route) { diff --git a/packages/umi-build-dev/src/plugins/commands/dev/createRouteMiddleware.js b/packages/umi-build-dev/src/plugins/commands/dev/createRouteMiddleware.js index 8c10925b8a8d..c25d29039b44 100644 --- a/packages/umi-build-dev/src/plugins/commands/dev/createRouteMiddleware.js +++ b/packages/umi-build-dev/src/plugins/commands/dev/createRouteMiddleware.js @@ -1,4 +1,5 @@ import getHtmlGenerator from '../getHtmlGenerator'; +import chunksToMap from '../build/chunksToMap'; export default function createRouteMiddleware(service) { return (req, res) => { @@ -8,7 +9,10 @@ export default function createRouteMiddleware(service) { res.setHeader('Content-Type', 'text/json'); res.send(JSON.stringify(service.routes)); } else { - const htmlGenerator = getHtmlGenerator(service); + const chunksMap = chunksToMap(service.__chunks); + const htmlGenerator = getHtmlGenerator(service, { + chunksMap, + }); const content = htmlGenerator.getMatchedContent(path); res.setHeader('Content-Type', 'text/html'); res.send(content); diff --git a/packages/umi-build-dev/src/plugins/commands/dev/index.js b/packages/umi-build-dev/src/plugins/commands/dev/index.js index e4211e51db05..85abcd94fb52 100644 --- a/packages/umi-build-dev/src/plugins/commands/dev/index.js +++ b/packages/umi-build-dev/src/plugins/commands/dev/index.js @@ -105,6 +105,7 @@ export default function(api) { startWatch(); }, onCompileDone({ isFirstCompile, stats }) { + service.__chunks = stats.compilation.chunks; service.applyPlugins('onDevCompileDone', { args: { isFirstCompile, diff --git a/packages/umi-plugin-react/test/chunks/.umirc.js b/packages/umi-plugin-react/test/chunks/.umirc.js new file mode 100644 index 000000000000..ec10e97777f0 --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/.umirc.js @@ -0,0 +1,30 @@ +export default { + plugins: [ + [ + '../../lib', + { + dynamicImport: { + webpackChunkName: true, + }, + chunks: ['vendors', 'umi'], + }, + ], + ], + chainWebpack(config) { + config.optimization.splitChunks({ + cacheGroups: { + vendors: { + name: 'vendors', + chunks: 'all', + test: /[\\/]node_modules[\\/](react|react-dom|react-router|react-router-dom)/, + }, + commons: { + name: 'commons', + chunks: 'async', + minChunks: 2, + minSize: 0, + }, + }, + }); + }, +}; diff --git a/packages/umi-plugin-react/test/chunks/a.js b/packages/umi-plugin-react/test/chunks/a.js new file mode 100644 index 000000000000..ba5d0e813943 --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/a.js @@ -0,0 +1 @@ +console.log('module a'); diff --git a/packages/umi-plugin-react/test/chunks/package.json b/packages/umi-plugin-react/test/chunks/package.json new file mode 100644 index 000000000000..9e26dfeeb6e6 --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/umi-plugin-react/test/chunks/pages/index.css b/packages/umi-plugin-react/test/chunks/pages/index.css new file mode 100644 index 000000000000..a4b84e2ef64c --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/pages/index.css @@ -0,0 +1,4 @@ + +.normal { + background: #95F279; +} diff --git a/packages/umi-plugin-react/test/chunks/pages/index.js b/packages/umi-plugin-react/test/chunks/pages/index.js new file mode 100755 index 000000000000..efa3b266b682 --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/pages/index.js @@ -0,0 +1,10 @@ +import styles from './index.css'; +import '../a'; + +export default function() { + return ( +
+

Page index

+
+ ); +} diff --git a/packages/umi-plugin-react/test/chunks/pages/users.css b/packages/umi-plugin-react/test/chunks/pages/users.css new file mode 100644 index 000000000000..f66d7d6983f1 --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/pages/users.css @@ -0,0 +1,4 @@ + +.normal { + background: #7DF279; +} diff --git a/packages/umi-plugin-react/test/chunks/pages/users.js b/packages/umi-plugin-react/test/chunks/pages/users.js new file mode 100755 index 000000000000..d7e3fc062b2b --- /dev/null +++ b/packages/umi-plugin-react/test/chunks/pages/users.js @@ -0,0 +1,10 @@ +import styles from './users.css'; +import '../a'; + +export default function() { + return ( +
+

Page users

+
+ ); +}