зеркало из https://github.com/mozilla/hubs.git
Add HandlebarsTemplatePlugin for rewriting asset urls. (#38)
* Add HandlebarsTemplatePlugin and asset helper. * Recompile on template change.
This commit is contained in:
Родитель
3361464c8f
Коммит
b12cf55789
|
@ -58,4 +58,7 @@ typings/
|
|||
.env
|
||||
|
||||
# webpack bundle
|
||||
public/app.bundle.js*
|
||||
public/*.bundle.js*
|
||||
public/*.html
|
||||
|
||||
.DS_Store
|
||||
|
|
39
README.md
39
README.md
|
@ -1,13 +1,44 @@
|
|||
# Mozilla Social Mixed Reality Client
|
||||
|
||||
A prototype client demonstrating a multi-user experience in WebVR. Built with [A-Frame](https://github.com/aframevr/aframe/)
|
||||
A prototype client demonstrating a multi-user experience in WebVR. Built with
|
||||
[A-Frame](https://github.com/aframevr/aframe/)
|
||||
|
||||
## Getting Started
|
||||
|
||||
To run the social client, type:
|
||||
To run the social client, run:
|
||||
|
||||
```
|
||||
```sh
|
||||
git clone https://github.com/mozilla/mr-social-client.git
|
||||
yarn install
|
||||
yarn run dev
|
||||
yarn start
|
||||
```
|
||||
|
||||
## Building Static Files
|
||||
|
||||
To bundle javascript and generate the html templates, run:
|
||||
|
||||
```sh
|
||||
yarn build
|
||||
```
|
||||
|
||||
### Using CDN Assets
|
||||
|
||||
If you are hosting your static assets at separate path from the html documents,
|
||||
the asset handlebars helper supports rewriting the base asset paths. To use it
|
||||
run:
|
||||
|
||||
```sh
|
||||
BASE_ASSETS_PATH="https://cdn.mysite.com/assets/" yarn build
|
||||
```
|
||||
|
||||
Ex.
|
||||
|
||||
```hbs
|
||||
<img src="{{asset "asseturl.png"}}"/>
|
||||
```
|
||||
|
||||
Will become:
|
||||
|
||||
```html
|
||||
<img src="https://cdn.mysite.com/assets/asseturl.png?c=1512428142413"/>
|
||||
```
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
"main": "src/index.js",
|
||||
"license": "MPL-2.0",
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"dev": "webpack-dev-server --https --host 0.0.0.0 --useLocalIp --open --config webpack.dev.js",
|
||||
"build": "webpack --config webpack.prod.js",
|
||||
"build": "NODE_ENV='production' webpack --config webpack.prod.js",
|
||||
"prettier": "prettier --write src/**/*.js"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -30,10 +31,13 @@
|
|||
"babel-minify-webpack-plugin": "^0.2.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"chokidar": "^1.7.0",
|
||||
"css-loader": "^0.28.7",
|
||||
"eslint": "^4.10.0",
|
||||
"eslint-config-prettier": "^2.6.0",
|
||||
"eslint-plugin-prettier": "^2.3.1",
|
||||
"fs-extra": "^4.0.2",
|
||||
"handlebars": "^4.0.11",
|
||||
"prettier": "^1.7.0",
|
||||
"style-loader": "^0.19.0",
|
||||
"webpack": "^3.6.0",
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
const Handlebars = require("handlebars");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const chokidar = require("chokidar");
|
||||
|
||||
class HandlebarsTemplatePlugin {
|
||||
constructor(options) {
|
||||
this.templatesPath = options.templatesPath;
|
||||
this.templateExtension = options.templateExtension || ".hbs";
|
||||
this.templateOptions = options.templateOptions || {};
|
||||
|
||||
if (options.helpers) {
|
||||
Object.keys(options.helpers).forEach(helperName => {
|
||||
Handlebars.registerHelper(helperName, options.helpers[helperName]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
apply(compiler) {
|
||||
compiler.plugin("watch-run", (compilation, callback) => {
|
||||
chokidar
|
||||
.watch(path.join(this.templatesPath, "*" + this.templateExtension))
|
||||
.on("change", () => {
|
||||
compiler.run(err => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
callback();
|
||||
});
|
||||
|
||||
compiler.plugin("emit", (compilation, callback) => {
|
||||
this.compileTemplates(compiler, compilation).then(callback);
|
||||
});
|
||||
}
|
||||
|
||||
// Compile all handlebars templates in the template directory and place them in the output directory.
|
||||
async compileTemplates(compiler, compilation) {
|
||||
const outputPath = compiler.options.output.path;
|
||||
const templateFiles = await fs.readdir(this.templatesPath);
|
||||
|
||||
const templatePromises = templateFiles
|
||||
.filter(filename => filename.indexOf(this.templateExtension) !== -1)
|
||||
.map(fileName => {
|
||||
const filePath = path.join(this.templatesPath, fileName);
|
||||
const outputFileName = fileName.replace(
|
||||
this.templateExtension,
|
||||
".html"
|
||||
);
|
||||
const outputFilePath = path.join(outputPath, outputFileName);
|
||||
|
||||
return this.compileTemplate(filePath, outputFilePath);
|
||||
});
|
||||
|
||||
await Promise.all(templatePromises);
|
||||
}
|
||||
|
||||
// Compile a single handlebars template given a file path and output file path.
|
||||
async compileTemplate(filePath, outputFilePath) {
|
||||
const templateStr = await fs.readFile(filePath);
|
||||
const template = Handlebars.compile(templateStr.toString());
|
||||
const compiledStr = template(this.templateOptions);
|
||||
return fs.writeFile(outputFilePath, compiledStr);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HandlebarsTemplatePlugin;
|
|
@ -12,6 +12,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="./lobby.bundle.js"></script>
|
||||
<script src="{{asset "lobby.bundle.js"}}"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>Mozilla Mixed Reality Social Client</title>
|
||||
<script src="https://webrtc.github.io/adapter/adapter-6.0.2.js"></script>
|
||||
<script src="./app.bundle.js"></script>
|
||||
<script src="{{asset "app.bundle.js" }}"></script>
|
||||
<style>
|
||||
.a-enter-vr {
|
||||
top: 90px;
|
||||
|
@ -14,7 +14,7 @@
|
|||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 10001;
|
||||
background: #eaeaea no-repeat url(assets/loading.gif) center center;
|
||||
background: #eaeaea no-repeat url({{asset "assets/loading.gif" }}) center center;
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
|
@ -32,19 +32,16 @@
|
|||
light="defaultLightsEnabled: false">
|
||||
|
||||
<a-assets>
|
||||
<img id="grid" src="assets/grid.png" crossorigin="anonymous" />
|
||||
<img id="sky" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg" crossorigin="anonymous" />
|
||||
<a-asset-item id="bot-head-mesh" src="{{asset "assets/avatars/Bot_Head_Mesh.glb" }}"></a-asset-item>
|
||||
<a-asset-item id="bot-body-mesh" src="{{asset "assets/avatars/Bot_Body_Mesh.glb" }}"></a-asset-item>
|
||||
<a-asset-item id="bot-left-hand-mesh" src="{{asset "assets/avatars/Bot_LeftHand_Mesh.glb" }}"></a-asset-item>
|
||||
<a-asset-item id="bot-right-hand-mesh" src="{{asset "assets/avatars/Bot_RightHand_Mesh.glb"}}"></a-asset-item>
|
||||
|
||||
<a-asset-item id="bot-head-mesh" src="assets/avatars/Bot_Head_Mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="bot-body-mesh" src="assets/avatars/Bot_Body_Mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="bot-left-hand-mesh" src="assets/avatars/Bot_LeftHand_Mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="bot-right-hand-mesh" src="assets/avatars/Bot_RightHand_Mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="watch-model" src="{{asset "assets/hud/watch.gltf"}}"></a-asset-item>
|
||||
|
||||
<a-asset-item id="watch-model" src="assets/hud/watch.gltf"></a-asset-item>
|
||||
|
||||
<a-asset-item id="meeting-space1-mesh" src="assets/environments/MeetingSpace1_mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="outdoor-facade-mesh" src="assets/environments/OutdoorFacade_mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="floor-nav-mesh" src="assets/environments/FloorNav_mesh.glb"></a-asset-item>
|
||||
<a-asset-item id="meeting-space1-mesh" src="{{asset "assets/environments/MeetingSpace1_mesh.glb"}}"></a-asset-item>
|
||||
<a-asset-item id="outdoor-facade-mesh" src="{{asset "assets/environments/OutdoorFacade_mesh.glb"}}"></a-asset-item>
|
||||
<a-asset-item id="floor-nav-mesh" src="{{asset "assets/environments/FloorNav_mesh.glb"}}"></a-asset-item>
|
||||
|
||||
<!-- Templates -->
|
||||
<script id="head-template" type="text/html">
|
||||
|
@ -144,7 +141,7 @@
|
|||
>
|
||||
<a-entity
|
||||
id="watch"
|
||||
cached-gltf-model="assets/hud/watch.gltf"
|
||||
cached-gltf-model="#watch-model"
|
||||
position="0 0.0015 0.147"
|
||||
rotation="3.5 0 0"
|
||||
>
|
|
@ -1,4 +1,6 @@
|
|||
const path = require("path");
|
||||
const HandlebarsTemplatePlugin = require("./templates/HandlebarsTemplatePlugin");
|
||||
const Handlebars = require("handlebars");
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
|
@ -12,7 +14,7 @@ module.exports = {
|
|||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /.js$/,
|
||||
test: /\.js$/,
|
||||
include: [path.resolve(__dirname, "src")],
|
||||
exclude: [path.resolve(__dirname, "node_modules")],
|
||||
loader: "babel-loader"
|
||||
|
@ -22,5 +24,28 @@ module.exports = {
|
|||
use: ["style-loader", "css-loader"]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new HandlebarsTemplatePlugin({
|
||||
templatesPath: path.resolve(__dirname, "templates"),
|
||||
helpers: {
|
||||
/**
|
||||
* Register a handlebars helper that prepends the base asset path.
|
||||
* Useful for things like placing assets on a CDN and cache busting.
|
||||
* Example:
|
||||
* input: <img src="{{asset "asset.png"}}"/>
|
||||
* output: <img src="https://cdn.mysite.com/asset.png?c="/>
|
||||
*/
|
||||
asset: assetPath => {
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
const baseAssetsPath = process.env.BASE_ASSETS_PATH || "/";
|
||||
const cacheBustQueryString = isProd ? "?c=" + Date.now() : "";
|
||||
|
||||
const url = baseAssetsPath + assetPath + cacheBustQueryString;
|
||||
|
||||
return new Handlebars.SafeString(url);
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
51
yarn.lock
51
yarn.lock
|
@ -306,7 +306,7 @@ async@0.2.x:
|
|||
version "0.2.10"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
|
||||
|
||||
async@^1.5.2:
|
||||
async@^1.4.0, async@^1.5.2:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
|
||||
|
||||
|
@ -2620,6 +2620,14 @@ fs-exists-sync@^0.1.0:
|
|||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
|
||||
|
||||
fs-extra@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
@ -2780,7 +2788,7 @@ globby@^6.1.0:
|
|||
pify "^2.0.0"
|
||||
pinkie-promise "^2.0.0"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
||||
version "4.1.11"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
||||
|
||||
|
@ -2788,6 +2796,16 @@ handle-thing@^1.2.5:
|
|||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
|
||||
|
||||
handlebars@^4.0.11:
|
||||
version "4.0.11"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc"
|
||||
dependencies:
|
||||
async "^1.4.0"
|
||||
optimist "^0.6.1"
|
||||
source-map "^0.4.4"
|
||||
optionalDependencies:
|
||||
uglify-js "^2.6"
|
||||
|
||||
har-schema@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
|
||||
|
@ -3343,6 +3361,12 @@ json5@^0.5.0, json5@^0.5.1:
|
|||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonify@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
|
||||
|
@ -3678,6 +3702,10 @@ minimist@^1.1.3, minimist@^1.2.0:
|
|||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
|
||||
minimist@~0.0.1:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
|
||||
|
||||
mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
|
@ -3945,6 +3973,13 @@ opn@^5.1.0:
|
|||
dependencies:
|
||||
is-wsl "^1.1.0"
|
||||
|
||||
optimist@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
|
||||
dependencies:
|
||||
minimist "~0.0.1"
|
||||
wordwrap "~0.0.2"
|
||||
|
||||
optionator@^0.8.2:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
|
||||
|
@ -5136,7 +5171,7 @@ source-map-support@^0.4.15:
|
|||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map@^0.4.2:
|
||||
source-map@^0.4.2, source-map@^0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
|
||||
dependencies:
|
||||
|
@ -5530,7 +5565,7 @@ ua-parser-js@^0.7.9:
|
|||
version "0.7.17"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac"
|
||||
|
||||
uglify-js@^2.8.29:
|
||||
uglify-js@^2.6, uglify-js@^2.8.29:
|
||||
version "2.8.29"
|
||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
|
||||
dependencies:
|
||||
|
@ -5577,6 +5612,10 @@ uniqs@^2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
|
@ -5812,6 +5851,10 @@ wordwrap@0.0.2:
|
|||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
|
||||
|
||||
wordwrap@~0.0.2:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
|
||||
|
||||
wordwrap@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
|
||||
|
|
Загрузка…
Ссылка в новой задаче