diff --git a/.circleci/config.yml b/.circleci/config.yml index 507706803..2fe14ad6e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -92,7 +92,7 @@ jobs: - save_cache: key: build-cache-{{ .Branch }}-{{ .Revision }} paths: - - ./node_modules/.cache/hard-source + - ./node_modules/.cache/babel-loader - persist_to_workspace: root: . paths: dist diff --git a/client/coral-embed-stream/src/tabs/configure/components/QuestionBoxBuilder.js b/client/coral-embed-stream/src/tabs/configure/components/QuestionBoxBuilder.js index 30fd8842c..ae60770d4 100644 --- a/client/coral-embed-stream/src/tabs/configure/components/QuestionBoxBuilder.js +++ b/client/coral-embed-stream/src/tabs/configure/components/QuestionBoxBuilder.js @@ -25,7 +25,8 @@ class QuestionBoxBuilder extends React.Component { async loadEditor() { const { default: MarkdownEditor, - } = await import('coral-framework/components/MarkdownEditor'); + } = await import(/* webpackChunkName: "markdownEditor" */ + 'coral-framework/components/MarkdownEditor'); return this.setState({ loading: false, diff --git a/middleware/staticTemplate.js b/middleware/staticTemplate.js index 5a7c34b60..b7d01feb4 100644 --- a/middleware/staticTemplate.js +++ b/middleware/staticTemplate.js @@ -1,4 +1,7 @@ const SettingsService = require('../services/settings'); +const fs = require('fs'); +const path = require('path'); +const { merge } = require('lodash'); const { BASE_URL, @@ -34,6 +37,45 @@ const attachStaticLocals = locals => { } }; +// MANIFESTS are all the manifests accessible by Talk. +const MANIFESTS = ['../dist/manifest.json', '../dist/manifest.embed.json']; + +// getManifest will retrieve the manifest files and parse the JSON. +function getManifest() { + return merge( + {}, + ...MANIFESTS.map(f => + fs.readFileSync(path.resolve(__dirname, f), 'utf8') + ).map(JSON.parse) + ); +} + +/** + * resolve is a function that can be used in templates to resolve an asset from + * the manifest. In production, the manifest is cached. + */ +const resolve = (() => { + if (process.env.NODE_ENV === 'production') { + // In production, we should attempt to load the manifest early. + const manifest = getManifest(); + + return key => `${STATIC_URL}static/${manifest[key]}`; + } + + // In dev mode, we are more forgiving and we always load the + // newest version of the manifest. + return key => { + try { + const manifest = getManifest(); + + return `${STATIC_URL}static/${manifest[key]}`; + } catch (err) { + console.warn(err); + return ''; + } + }; +})(); + module.exports = async (req, res, next) => { try { // Attach the custom css url. @@ -46,6 +88,10 @@ module.exports = async (req, res, next) => { // Always attach the locals. attachStaticLocals(res.locals); + // Resolve will help resolving paths to static files + // using the manifest. + res.locals.resolve = resolve; + // Forward the request. next(); }; diff --git a/package.json b/package.json index d2453818f..93b9d0205 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,6 @@ "graphql-tag": "^1.2.3", "graphql-tools": "^0.10.1", "hammerjs": "^2.0.8", - "hard-source-webpack-plugin": "^0.6.0", "helmet": "3.8.2", "history": "^3.0.0", "hjson": "^3.1.1", @@ -214,6 +213,7 @@ "enzyme-adapter-react-15": "^1.0.0", "eslint": "^4.5.0", "eslint-plugin-mocha": "^4.11.0", + "extract-text-webpack-plugin": "^3.0.2", "husky": "^0.14.3", "identity-obj-proxy": "^3.0.0", "ip": "^1.1.5", @@ -222,11 +222,13 @@ "lint-staged": "^7.0.0", "mocha": "^3.1.2", "mocha-junit-reporter": "^1.12.1", + "name-all-modules-plugin": "^1.0.1", "nightwatch": "^0.9.16", "nodemon": "^1.11.0", "selenium-standalone": "^6.11.0", "sinon": "^3.2.1", "sinon-chai": "^2.13.0", + "webpack-manifest-plugin": "^2.0.0-rc.2", "yaml-lint": "^1.0.0" }, "engines": { diff --git a/views/admin.ejs b/views/admin.ejs index 939da0dcf..1ecca390e 100644 --- a/views/admin.ejs +++ b/views/admin.ejs @@ -3,8 +3,6 @@