Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(umi-plugin-react): support config chunks, scripts, headScripts, metas and links #1097

Merged
merged 4 commits into from
Sep 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/plugin/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions docs/zh/plugin/develop.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ api.addHTMLScript({

在 HTML 头部添加脚本。

### modifyHTMLChunks

修改 chunks 。

### modifyHTMLWithAST

修改 HTML,基于 cheerio 。
Expand Down
1 change: 1 addition & 0 deletions packages/umi-build-dev/src/PluginAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export default class PluginAPI {
'addHTMLScript',
'addHTMLStyle',
'addHTMLHeadScript',
'modifyHTMLChunks',
'onGenerateFiles',
'onHTMLRebuild',
'modifyDefaultConfig',
Expand Down
38 changes: 26 additions & 12 deletions packages/umi-build-dev/src/html/HTMLGenerator.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -246,6 +244,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 || '/';
Expand Down Expand Up @@ -273,8 +274,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);
Expand All @@ -286,9 +293,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}`,
});
}
});
}

Expand Down Expand Up @@ -322,7 +334,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 });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import getHtmlGenerator from '../getHtmlGenerator';
import chunksToMap from '../build/chunksToMap';

export default function createRouteMiddleware(service) {
return (req, res) => {
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions packages/umi-build-dev/src/plugins/commands/dev/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export default function(api) {
startWatch();
},
onCompileDone({ isFirstCompile, stats }) {
service.__chunks = stats.compilation.chunks;
service.applyPlugins('onDevCompileDone', {
args: {
isFirstCompile,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions packages/umi-plugin-react/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ export default function(api, option) {
hardSource: () => require('./plugins/hardSource').default,
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,
metas: () => require('./plugins/metas').default,

// misc
dva: () => require('./plugins/dva').default,
locale: () => require('./plugins/locale').default,
Expand Down
11 changes: 11 additions & 0 deletions packages/umi-plugin-react/src/plugins/chunks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function(api, option) {
api.onOptionChange(newOption => {
option = newOption;
api.rebuildHTML();
api.refreshBrowser();
});

api.modifyHTMLChunks(() => {
return option;
});
}
11 changes: 11 additions & 0 deletions packages/umi-plugin-react/src/plugins/headScripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function(api, option) {
api.onOptionChange(newOption => {
option = newOption;
api.rebuildHTML();
api.refreshBrowser();
});

api.addHTMLHeadScript(() => {
return option;
});
}
11 changes: 11 additions & 0 deletions packages/umi-plugin-react/src/plugins/links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function(api, option) {
api.onOptionChange(newOption => {
option = newOption;
api.rebuildHTML();
api.refreshBrowser();
});

api.addHTMLLink(() => {
return option;
});
}
11 changes: 11 additions & 0 deletions packages/umi-plugin-react/src/plugins/metas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function(api, option) {
api.onOptionChange(newOption => {
option = newOption;
api.rebuildHTML();
api.refreshBrowser();
});

api.addHTMLMeta(() => {
return option;
});
}
1 change: 0 additions & 1 deletion packages/umi-plugin-react/src/plugins/mobile/fastClick.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/umi-plugin-react/src/plugins/mobile/hd.js

This file was deleted.

11 changes: 11 additions & 0 deletions packages/umi-plugin-react/src/plugins/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function(api, option) {
api.onOptionChange(newOption => {
option = newOption;
api.rebuildHTML();
api.refreshBrowser();
});

api.addHTMLScript(() => {
return option;
});
}
30 changes: 30 additions & 0 deletions packages/umi-plugin-react/test/chunks/.umirc.js
Original file line number Diff line number Diff line change
@@ -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,
},
},
});
},
};
1 change: 1 addition & 0 deletions packages/umi-plugin-react/test/chunks/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('module a');
1 change: 1 addition & 0 deletions packages/umi-plugin-react/test/chunks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
4 changes: 4 additions & 0 deletions packages/umi-plugin-react/test/chunks/pages/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.normal {
background: #95F279;
}
10 changes: 10 additions & 0 deletions packages/umi-plugin-react/test/chunks/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import styles from './index.css';
import '../a';

export default function() {
return (
<div className={styles.normal}>
<h1>Page index</h1>
</div>
);
}
4 changes: 4 additions & 0 deletions packages/umi-plugin-react/test/chunks/pages/users.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.normal {
background: #7DF279;
}
10 changes: 10 additions & 0 deletions packages/umi-plugin-react/test/chunks/pages/users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import styles from './users.css';
import '../a';

export default function() {
return (
<div className={styles.normal}>
<h1>Page users</h1>
</div>
);
}
16 changes: 16 additions & 0 deletions packages/umi-plugin-react/test/normal.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
8 changes: 8 additions & 0 deletions packages/umi-plugin-react/test/normal/.umirc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: '<%= PUBLIC_PATH %>bar' }],
links: [{ id: 'link1', foo: 'bar' }],
},
],
],
Expand Down
1 change: 1 addition & 0 deletions packages/umi-plugin-react/test/normal/public/script2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.scripts.push('script2');