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: enable contenthash for assets #161

Merged
merged 11 commits into from
Apr 18, 2019
4 changes: 2 additions & 2 deletions examples/simple/client/script/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ export default class View extends React.Component {
</head>
<body>
<div id="container" dangerouslySetInnerHTML={{ __html: html }} />
<script src={helper.asset('/manifest.js')} />
<script src={helper.asset('/script.js')} />
<script src={helper.asset('manifest.js')} />
<script src={helper.asset('script.js')} />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion examples/simple/client/style/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class View extends React.Component {
<html>
<head>
<title>Styling</title>
<link rel="stylesheet" href={helper.asset('/style.css')} />
<link rel="stylesheet" href={helper.asset('style.css')} />
</head>
<body>
<h1 className="title">Styling Page</h1>
Expand Down
8 changes: 8 additions & 0 deletions examples/simple/config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ const path = require('path');

module.exports = appInfo => ({
keys: 'secrets',
webpack: {
custom: {
assetWithHash: true,
},
},
view: {
useHashAsset: true,
},
static: {
dir: [
{
Expand Down
9 changes: 9 additions & 0 deletions examples/simple/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"manifest.js": "/build/manifest_2b248f68.js",
"index.js": "/build/index_ec3f4aa7.js",
"script.js": "/build/script_f2970f26.js",
"script.css": "/build/script_93bb8fc6.css",
"static.js": "/build/static_0e65a2e0.js",
"style.js": "/build/style_bb8f1203.js",
"style.css": "/build/style_93bb8fc6.css"
}
1 change: 1 addition & 0 deletions packages/beidou-view-rax/config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = appInfo => ({
assetPath: '/build/',
},
view: {
useHashAsset: false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个配置是在beidou-view的插件下用的,最好放在beidou-view的配置下

mapping: {
'.jsx': 'rax',
},
Expand Down
1 change: 1 addition & 0 deletions packages/beidou-view-react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = appInfo => ({
assetPath: '/build/',
},
view: {
useHashAsset:false,
defaultViewEngine: 'react',
defaultExtension: '.jsx',
// Isomorphic directories
Expand Down
1 change: 1 addition & 0 deletions packages/beidou-view-react/config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module.exports = (appInfo) => {
placeHolder: '<!--$render$-->',
},
view: {
useHashAsset: false,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同上

defaultViewEngine: 'react',
defaultExtension: isTs ? '.tsx' : '.jsx',
root: `${path.join(appInfo.baseDir, 'app/views')},${path.join(
Expand Down
17 changes: 17 additions & 0 deletions packages/beidou-view/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const { getAssetManifest } = require('./lib/utils');

module.exports = (app) => {
// get asset with hash from cwd/manifes.json;
if (app.config.view.useHashAsset) {
if (app.config.env === 'local') {
app.coreLogger.warn(
'Detect view.useHashAsset in local env, will ignore it.'
);
app.config.view.useHashAsset = false;
return;
}
app.assetManifest = getAssetManifest(app.baseDir);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

获取mapping资源文件最好可配置

}
};
4 changes: 3 additions & 1 deletion packages/beidou-view/app/extend/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ const helper = {
* @param {Object} config asset config
*/
[Symbol.for('beidou#asset')](filename, config) {
if (this.app.config.view.useHashAsset && this.app.assetManifest[filename]) {
return this.app.assetManifest[filename];
}
const assetHost = config.host || config.assetHost;
const { assetPath } = config;

if (!assetHost) {
return concatUrl(assetPath, filename);
}
Expand Down
11 changes: 11 additions & 0 deletions packages/beidou-view/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const path = require('path');
const fs = require('fs');
const normalizeUrl = require('normalizeurl');

exports.concatUrl = function (...pathes) {
Expand All @@ -20,3 +22,12 @@ exports.concatUrl = function (...pathes) {
};

exports.normalizeUrl = normalizeUrl;
exports.getAssetManifest = function (baseDir) {
const manifestFile = path.join(baseDir, './manifest.json');
if (fs.existsSync(manifestFile)) {
const raw = fs.readFileSync(manifestFile, { encoding: 'utf8' });
return JSON.parse(raw);
} else {
throw new Error('Cannot find manifest.json! Please check webpack.custom.assetWithHash config.');
}
};

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import assert from 'assert';

const testStr = 'base view test';

/**
* Text component
*
* @export
* @class View
* @extends {React.Component}
*/
export default class View {
static async getInitialProps() {
return {
title: 'beidou',
};
}
static async getStore() {
return {
getState: () => ({ testStr }),
};
}

static async getPartial(props) {
assert(props.state === '{"testStr":"base view test"}');
return { partial: '', list: ['a', 'b', 'c'], store: 'store' };
}

render({ partial, list, store, title }) {
// See view.test.js BaseView.prototype.renderElement
const partialResult = 'fake renderElement';
assert(partial === partialResult);

assert(list.length === 3);
for (const item of list) {
assert(item === partialResult);
}

assert(store === partialResult);

assert(title === 'beidou');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';


module.exports = _ => ({
view: {
useHashAsset: true,
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"index.js": "/build/index_ec3f4aa7.js"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "beidou-test-view-use-hash-asset-app"
}
79 changes: 78 additions & 1 deletion packages/beidou-view/test/view.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('test/view.test.js', () => {
const { concatUrl } = utils;
assert(
concatUrl('http://beidou.net', 'docs', 'quickstart') ===
'http://beidou.net/docs/quickstart'
'http://beidou.net/docs/quickstart'
);
assert(
concatUrl('/root/', '/docs/', '/quickstart/') === '/root/docs/quickstart/'
Expand Down Expand Up @@ -103,4 +103,81 @@ describe('test/view.test.js', () => {
assert(url === 'http://127.0.0.1/build/index.js');
});
});

describe('UseHashAsset view', () => {
let app;

before((done) => {
mock.env('local');
app = mock.app({
baseDir: './use-hash-asset-app',
framework,
});
app.ready(done);
});
after(() => {
app.close();
});

it('should use asset without hash in local env', () => {
const ctx = app.mockContext();
const asset = ctx.helper[Symbol.for('beidou#asset')].bind(ctx.helper);
let url = asset('index.js', {
assetPath: 'build',
});
assert(url === 'build/index.js');

url = asset('index.js', {
host: 'http://127.0.0.1',
assetPath: 'build',
});
assert(url === 'http://127.0.0.1/build/index.js');

url = asset('index.js', {
host: '127.0.0.1',
assetPath: 'build',
});
assert(url === 'http://127.0.0.1/build/index.js');
});
});

describe('UseHashAsset view', () => {
let app;

before((done) => {
mock.env('prod');
app = mock.app({
baseDir: './use-hash-asset-app',
framework,
});
app.ready(done);
});
after(() => {
app.close();
});

it('should use asset with hash in local env', () => {
const ctx = app.mockContext();
const asset = ctx.helper[Symbol.for('beidou#asset')].bind(ctx.helper);
let url = asset('index.js', {
assetPath: 'build',
});
assert(url === '/build/index_ec3f4aa7.js');

url = asset('index.js', {
host: 'http://127.0.0.1',
assetPath: 'build',
});
assert(url === '/build/index_ec3f4aa7.js');

url = asset('index.js', {
host: '127.0.0.1',
assetPath: 'build',
});
assert(url === '/build/index_ec3f4aa7.js');

url = asset('index.js');
assert(url === '/build/index_ec3f4aa7.js');
});
});
});
4 changes: 4 additions & 0 deletions packages/beidou-webpack/README-ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ exports.webpack = {
exports.webpack = {
custom: {
// configPath: 'path/to/webpack/config/file',
depth:1,
assetWithHash: false,
},
output: {
path: './build',
Expand Down Expand Up @@ -138,6 +140,8 @@ module.exports = {

**custom.depth**: 自定义 entry 扫描深度默认 1

**custom.assetWithHash**: 开启此配置后,打包生成的js,css等资源将会以`[name]_[contenthash:8]`形式命名,可用于缓存。(如果`config.view.useHashAsset`开启,beidou将会在生产环境中的页面上引用这些哈希资源,配合`publicPath`,效果更佳哦)

**custom.proxy**: 定义由webpack完全代理的url规则

如:
Expand Down
2 changes: 2 additions & 0 deletions packages/beidou-webpack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ module.exports = {

**custom.depth**: define the depth of entry scanning

**custom.assetWithHash**: when set true, assets such as '.js', '.css' will be named as `[name]_[contenthash:8]`, which can be cache-friendly.(If `config.view.useHashAsset` is set true, beidou will use hashed assets on the page if not local env. You can set CDN path in `publicPath`, which will be included.)

**custom.proxy**: define the url match for webpack proxy

e.g.:
Expand Down
1 change: 1 addition & 0 deletions packages/beidou-webpack/config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module.exports = appInfo => ({
// keep this key name sync with webpack.common.js reservedKey
custom: {
depth: 1,
assetWithHash: false,
// configPath: 'path/to/webpack/config/file',
},
mode: 'development',
Expand Down
18 changes: 16 additions & 2 deletions packages/beidou-webpack/config/webpack/webpack.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
process.traceDeprecation = true;

const webpack = require('webpack');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const common = require('./webpack.common');
const { common, reservedKey } = require('./webpack.common');
const ManifestPlugin = require('webpack-manifest-plugin');
const {
imageLoaderConfig,
fileLoaderConfig,
Expand All @@ -18,6 +20,7 @@ module.exports = (app, entry, dev) => {
const { pkg } = app.config;
const factory = app.webpackFactory;
const typescript = pkg && pkg.config && pkg.config.typescript;
const reservedConfig = app.config.webpack[reservedKey];
common(app, entry, dev);
[
{
Expand Down Expand Up @@ -62,7 +65,6 @@ module.exports = (app, entry, dev) => {
if (!dev) {
factory.set('mode', 'production');
factory.addPlugin('DefinePlugin');

factory.set('optimization', {
minimizer: [
new TerserPlugin({
Expand Down Expand Up @@ -92,5 +94,17 @@ module.exports = (app, entry, dev) => {
'HotModuleReplacementPlugin'
);
}
if (reservedConfig.assetWithHash && !dev) {
factory.addPlugin(ManifestPlugin,
{ fileName: path.join(app.baseDir, 'manifest.json') },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapping资源路径最好可配置资源路径。
可参考beidou-isomophic 和 beidou-webpack的共用配置,如不存在这个配置,可使用默认值。
建议是不是也可以看看 assetWithHash也共用一个配置

'WebpackManifestPlugin'
);
factory
.setPlugin(
ExtractTextPlugin,
'[name]_[md5:contenthash:hex:8].css',
'ExtractTextPlugin'
);
}
return factory.getConfig();
};
8 changes: 7 additions & 1 deletion packages/beidou-webpack/config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ const path = require('path');

const reservedKey = 'custom';

module.exports = (app, entry, dev) => {
exports.common = (app, entry, dev) => {
const webpackConfig = app.config.webpack;
const { output } = webpackConfig;
if (!path.isAbsolute(output.path)) {
output.path = path.join(app.baseDir, output.path);
}
if (!dev && webpackConfig[reservedKey].assetWithHash) {
output.filename = '[name]_[chunkhash:8].js';
output.chunkFilename = '[name]_[chunkhash:8].js';
}

const module = {
// makes missing exports an error instead of warning
Expand Down Expand Up @@ -43,3 +47,5 @@ module.exports = (app, entry, dev) => {

app.webpackFactory.reset(finalConfig);
};

exports.reservedKey = reservedKey;