Skip to content

Commit b2fdb07

Browse files
ahungrynoobnjugray
authored andcommitted
feat: enable contenthash for assets (#161)
* feat: enable contenthash for assets * test: add glob to existsSync * test: fix it.only * fix: optimize content hash feature * fix: typo * test(beidou-webpack): remove done * fix: 在beidou-view 统一初始化 hashAssetPath * fix: user .manifes.json insteadof manifest.json * test: improve cov * fix: compatible with assetHost and assetPath
1 parent bd4bd56 commit b2fdb07

File tree

46 files changed

+646
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+646
-26
lines changed

examples/simple/.manifest.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"manifest.js": "manifest_6498f2ed.js",
3+
"index.js": "index_48ebde7c.js",
4+
"script.js": "script_3a4833fb.js",
5+
"script.css": "script_93bb8fc6.css",
6+
"static.js": "static_3f3fa875.js",
7+
"style.js": "style_6d3bbe58.js",
8+
"style.css": "style_93bb8fc6.css"
9+
}

examples/simple/client/script/index.jsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ export default class View extends React.Component {
2323
<html>
2424
<head>
2525
<title>Script</title>
26-
<link rel="stylesheet" href={helper.asset('/script.css')} />
26+
<link rel="stylesheet" href={helper.asset('script.css')} />
2727
</head>
2828
<body>
2929
<div id="container" dangerouslySetInnerHTML={{ __html: html }} />
30-
<script src={helper.asset('/manifest.js')} />
31-
<script src={helper.asset('/script.js')} />
30+
<script src={helper.asset('manifest.js')} />
31+
<script src={helper.asset('script.js')} />
3232
</body>
3333
</html>
3434
);

examples/simple/client/style/index.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default class View extends React.Component {
1616
<html>
1717
<head>
1818
<title>Styling</title>
19-
<link rel="stylesheet" href={helper.asset('/style.css')} />
19+
<link rel="stylesheet" href={helper.asset('style.css')} />
2020
</head>
2121
<body>
2222
<h1 className="title">Styling Page</h1>

examples/simple/config/config.default.js

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const path = require('path');
44

55
module.exports = appInfo => ({
66
keys: 'secrets',
7+
view: {
8+
useHashAsset: true,
9+
},
710
static: {
811
dir: [
912
{

packages/beidou-view-react/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module.exports = appInfo => ({
3535
assetPath: '/build/',
3636
},
3737
view: {
38+
useHashAsset:false,
3839
defaultViewEngine: 'react',
3940
defaultExtension: '.jsx',
4041
// Isomorphic directories

packages/beidou-view/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
55
Used by internal react and rax plugins.
66

7+
# Config
8+
9+
If `config.view.useHashAsset` is set true, beidou will use hashed assets on the page if not local env with the help of `webpack build`. You can set CDN path in `publicPath`, which will be included.
10+
Remember that, you should run `beidou build` first before use this feature.
11+
12+
You can define the assets mapping file with `config.view.hashAssetPath`, the default value of which is `path.join(appInfo.baseDir, '.manifest.json')`.
13+
714
# Middlewares
815

916
We introduced **View Middlewares** mechanism since `v1.0.0`. The rendering process is fully defined by a combination of middlewares, which means you can redefined them or add custom ones if needed.

packages/beidou-view/app.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const { getAssetManifest } = require('./lib/utils');
5+
6+
module.exports = (app) => {
7+
// get asset with hash from cwd/manifes.json;
8+
if (app.config.view.useHashAsset) {
9+
// define hashAssetPath once here,and according to beidou-core, beidou-view will be loaded first.
10+
app.config.view.hashAssetPath =
11+
app.config.view.hashAssetPath || path.join(app.baseDir, '.manifest.json');
12+
if (app.config.env === 'local' || app.config.env === 'unittest') {
13+
app.coreLogger.warn(
14+
`Detect view.useHashAsset in ${app.config.env} env, will ignore it.`
15+
);
16+
app.assetManifest = {};
17+
return;
18+
}
19+
20+
app.assetManifest = getAssetManifest(app.config.view.hashAssetPath);
21+
}
22+
};

packages/beidou-view/app/extend/helper.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ const helper = {
88
* @param {Object} config asset config
99
*/
1010
[Symbol.for('beidou#asset')](filename, config) {
11+
if (this.app.config.view.useHashAsset && this.app.assetManifest[filename]) {
12+
filename = this.app.assetManifest[filename];
13+
}
1114
const assetHost = config.host || config.assetHost;
1215
const { assetPath } = config;
13-
1416
if (!assetHost) {
1517
return concatUrl(assetPath, filename);
1618
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const path = require('path');
2+
3+
module.exports = appInfo => ({
4+
view: {
5+
useHashAsset: false,
6+
hashAssetPath: path.join(appInfo.baseDir, '.manifest.json'),
7+
},
8+
});

packages/beidou-view/lib/utils.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'use strict';
22

3+
const fs = require('fs');
34
const normalizeUrl = require('normalizeurl');
45

56
exports.concatUrl = function (...pathes) {
@@ -20,3 +21,13 @@ exports.concatUrl = function (...pathes) {
2021
};
2122

2223
exports.normalizeUrl = normalizeUrl;
24+
exports.getAssetManifest = function (hashAssetPath) {
25+
if (fs.existsSync(hashAssetPath)) {
26+
const raw = fs.readFileSync(hashAssetPath, { encoding: 'utf8' });
27+
return JSON.parse(raw);
28+
} else {
29+
throw new Error(
30+
`Cannot find ${hashAssetPath}! Please check view.hashAssetPath config.`
31+
);
32+
}
33+
};

packages/beidou-view/test/fixtures/hash-asset-throw/build/index_ec3f4aa7.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import assert from 'assert';
2+
3+
const testStr = 'base view test';
4+
5+
/**
6+
* Text component
7+
*
8+
* @export
9+
* @class View
10+
* @extends {React.Component}
11+
*/
12+
export default class View {
13+
static async getInitialProps() {
14+
return {
15+
title: 'beidou',
16+
};
17+
}
18+
static async getStore() {
19+
return {
20+
getState: () => ({ testStr }),
21+
};
22+
}
23+
24+
static async getPartial(props) {
25+
assert(props.state === '{"testStr":"base view test"}');
26+
return { partial: '', list: ['a', 'b', 'c'], store: 'store' };
27+
}
28+
29+
render({ partial, list, store, title }) {
30+
// See view.test.js BaseView.prototype.renderElement
31+
const partialResult = 'fake renderElement';
32+
assert(partial === partialResult);
33+
34+
assert(list.length === 3);
35+
for (const item of list) {
36+
assert(item === partialResult);
37+
}
38+
39+
assert(store === partialResult);
40+
41+
assert(title === 'beidou');
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
const path = require('path');
3+
4+
module.exports = _ => ({
5+
view: {
6+
useHashAsset: true,
7+
hashAssetPath: '/foo/bar.json'
8+
},
9+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "beidou-test-view-use-hash-asset-app"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"index.js": "index_ec3f4aa7.js"
3+
}

packages/beidou-view/test/fixtures/use-hash-asset-app/build/index_ec3f4aa7.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import assert from 'assert';
2+
3+
const testStr = 'base view test';
4+
5+
/**
6+
* Text component
7+
*
8+
* @export
9+
* @class View
10+
* @extends {React.Component}
11+
*/
12+
export default class View {
13+
static async getInitialProps() {
14+
return {
15+
title: 'beidou',
16+
};
17+
}
18+
static async getStore() {
19+
return {
20+
getState: () => ({ testStr }),
21+
};
22+
}
23+
24+
static async getPartial(props) {
25+
assert(props.state === '{"testStr":"base view test"}');
26+
return { partial: '', list: ['a', 'b', 'c'], store: 'store' };
27+
}
28+
29+
render({ partial, list, store, title }) {
30+
// See view.test.js BaseView.prototype.renderElement
31+
const partialResult = 'fake renderElement';
32+
assert(partial === partialResult);
33+
34+
assert(list.length === 3);
35+
for (const item of list) {
36+
assert(item === partialResult);
37+
}
38+
39+
assert(store === partialResult);
40+
41+
assert(title === 'beidou');
42+
}
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
4+
module.exports = _ => ({
5+
view: {
6+
useHashAsset: true,
7+
},
8+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "beidou-test-view-use-hash-asset-app"
3+
}

0 commit comments

Comments
 (0)