Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Commit

Permalink
fix(Theme Editor): Allow serving from sub-dir by setting env.ASSET_PATH
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-ketch committed Mar 10, 2020
1 parent 88c0c1b commit 363ab07
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ after_success:

before_deploy:
- npm run build
- npm run docs
- ASSET_PATH=/thema/ npm run docs

deploy:
- provider: script
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build:browser": "webpack --mode production && tsc --emitDeclarationOnly --project tsconfig.browser.json",
"build:lib": "tsc --project tsconfig.lib.json",
"dev": "webpack-dev-server --mode development --hot --open",
"docs": "npm run build:lib && npm run docs:readme && npm run docs:gallery && npm run docs:app",
"docs": "npm run build:browser && npm run docs:readme && npm run docs:gallery && npm run docs:app",
"docs:readme": "ts-node --files src/scripts/readme.ts",
"docs:gallery": "ts-node --files src/scripts/gallery.ts",
"docs:app": "webpack --mode production --env.docs=true",
Expand Down
9 changes: 0 additions & 9 deletions src/demo/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@
* Provides an interface for switching of both example and theme.
* Used for human 🤗 user acceptance testing 👍 and robot 🤖
* visual regression testing.
*
* For HTML content and Javascript modules,
* switching is achieved via Parcel's [dynamic importing of modules]
* (https://parceljs.org/code_splitting.html). Note that this seems to load
* content for all examples and all themes i.e. it is not truly lazy.
*
* For CSS, this `import()` approach did not work, maybe because it loads all the
* CSS stylesheets into the global DOM. So, we take the approach of
* enabling/disabling `<link>` elements.
*/

import React from 'react'
Expand Down
3 changes: 2 additions & 1 deletion src/demo/editor/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import ReactDOM from 'react-dom'
import { examples } from '../../examples'
import { getExample, setExample } from '../utils/preview'
import { ViewportToggle } from './viewportToggle'
import { ASSET_PATH } from '../utils'

interface Props {
exampleContent: string[]
}

export const HeaderBase = (): JSX.Element => {
return (
<a href="/">
<a href={ASSET_PATH}>
<img src="https://stenci.la/img/stencila-logo.svg" />

<span className="name"> Thema</span>
Expand Down
2 changes: 1 addition & 1 deletion src/demo/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ main {
text-transform: capitalize;
}

& > a[href^='/editor?'] {
& > a[href*='editor?'] {
order: -1;
display: block;
border-bottom: 1px solid var(--color-neutral-400);
Expand Down
5 changes: 4 additions & 1 deletion src/demo/templates/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ <h4>Pull Request</h4>
</menu>

<main>
<iframe id="preview" src="/examples/articleReadme.html"></iframe>
<iframe
id="preview"
src="<%= ASSET_PATH %>examples/articleReadme.html"
></iframe>
</main>

<div id="modalTarget"></div>
Expand Down
2 changes: 2 additions & 0 deletions src/demo/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { translate } from '../../util'

export const ASSET_PATH = process.env.ASSET_PATH ?? '/'

export interface ThemeObject {
[key: string]: string
}
Expand Down
7 changes: 5 additions & 2 deletions src/demo/utils/preview.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { keys } from '.'
import { keys, ASSET_PATH } from '.'
import { examples, resolveExample } from '../../examples'
import { append, create } from '../../util'

Expand All @@ -21,7 +21,10 @@ export const setExample = (example: string): void => {

const preview = getPreview()
if (preview !== null && !preview.getAttribute('src')?.includes(example)) {
preview.setAttribute('src', `/examples/${resolveExample(example)}.html`)
preview.setAttribute(
'src',
`${ASSET_PATH}examples/${resolveExample(example)}.html`
)
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/demo/utils/theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { diff, objToVars, ThemeObject } from '.'
import { diff, objToVars, ThemeObject, ASSET_PATH } from '.'
import { styleEntry, themes } from '../../browser'
import { append, create, prepend } from '../../util'
import { keys } from './index'
Expand All @@ -11,7 +11,7 @@ import {

export const getThemeCSS = (theme: string): string => {
const req = new XMLHttpRequest()
req.open('GET', `/themes/${theme}/styles.css`, false)
req.open('GET', `${ASSET_PATH}themes/${theme}/styles.css`, false)
req.send(null)
return req.responseText
}
Expand All @@ -35,7 +35,7 @@ export const themeSet = (theme: string): void => {

const themeStyles = create('link')
themeStyles.setAttribute('rel', 'stylesheet')
themeStyles.setAttribute('href', `/themes/${theme}/${styleEntry}`)
themeStyles.setAttribute('href', `${ASSET_PATH}themes/${theme}/${styleEntry}`)
themeStyles.setAttribute('id', 'themaStyles')

const previewDoc = getPreviewDoc()
Expand All @@ -62,7 +62,7 @@ export const themeSet = (theme: string): void => {

const themeScript = previewDoc.createElement('script')
themeScript.type = 'text/javascript'
themeScript.src = `/themes/${theme}/index.js`
themeScript.src = `${ASSET_PATH}themes/${theme}/index.js`
themeScript.classList.add('themeScript')

previewDoc.body.appendChild(themeScript)
Expand Down
23 changes: 1 addition & 22 deletions src/scripts/examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,29 +85,8 @@ function articleAntibodies(): Promise<string | undefined> {
)
}

/**
* Transforms implicit relative URLs (`somePath.jpg`) found in the generated example HTML documents, into
* explicitly relative paths ('./somePath.jpg'). This allows the assets to be discovered inside the Theme Editor iframe.
*/
const qualifyRelativeUrls = (): void => {
EXAMPLES.map(example => {
const filePath = `${ex(example.name)}.html`
const contents = fs
.readFileSync(filePath)
.toString()
.replace(
/((?:src|href)=["'])(?!(?:https?)?:\/\/)([^/#.][^'"]+)/gm,
'$1./$2'
)

fs.writeFileSync(filePath, contents)
})
}

// Run each function
Promise.all(EXAMPLES.map(example => example()))
.then(() => qualifyRelativeUrls())
.catch(err => console.error(err))
Promise.all(EXAMPLES.map(example => example())).catch(err => console.error(err))

// Generate `../examples/examples.ts`
fs.writeFileSync(
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/gallery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ async function generateGallery(): Promise<void> {
theme,
await generateSummary(
theme,
`/editor?theme=${theme}`,
`./editor?theme=${theme}`,
example as Article
)
]
Expand Down
38 changes: 28 additions & 10 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
const { DefinePlugin, HotModuleReplacementPlugin } = require('webpack')

const contentSource = 'src'
const ASSET_PATH = process.env.ASSET_PATH || '/'

// Convert absolute filepaths to project relative ones to use as
// output destinations.
Expand All @@ -32,7 +33,9 @@ module.exports = (env = {}, { mode }) => {
const contentBase = isDocs ? 'docs' : 'dist'

const entries = [
'./src/**/*.{css,ts,tsx,ttf,woff,woff2}',
'./src/**/*.{css,ts,tsx,html,ttf,woff,woff2}',
// Template are used as basis for HtmlWebpackPlugin, and should not be used as an entry points
'!./src/demo/templates/*',
// Don’t compile test files for package distribution
'!**/*.{d,test}.ts',
// These files make use of Node APIs, and do not need to be packaged for Browser targets
Expand All @@ -43,7 +46,7 @@ module.exports = (env = {}, { mode }) => {
// Don’t build HTML demo files for package distribution
...(isDocs || isDevelopment
? ['./src/**/*.{jpg,png,gif}']
: ['!**/demo/*', '!**/examples/*'])
: ['!**/*.html', '!**/demo/*', '!**/examples/*'])
]

const entry = globby.sync(entries).reduce(
Expand All @@ -63,7 +66,10 @@ module.exports = (env = {}, { mode }) => {
new HtmlWebpackPlugin({
filename: 'editor/index.html',
template: './src/demo/templates/template.html',
chunks: ['demo/styles', 'themes/stencila/styles', 'demo/app.tsx']
chunks: ['demo/styles', 'themes/stencila/styles', 'demo/app.tsx'],
templateParameters: {
ASSET_PATH
}
}),
new HtmlWebpackPlugin({
filename: 'index.html',
Expand All @@ -80,11 +86,12 @@ module.exports = (env = {}, { mode }) => {
return {
entry,
resolve: {
extensions: ['.ts', '.tsx', '.js', '.css']
extensions: ['.ts', '.tsx', '.js', '.css', '.html']
},
mode: mode || 'development',
output: {
path: path.resolve(__dirname, contentBase),
publicPath: ASSET_PATH,
filename: '[name].js'
},
devServer: {
Expand All @@ -94,6 +101,7 @@ module.exports = (env = {}, { mode }) => {
plugins: [
new CleanWebpackPlugin(),
new DefinePlugin({
'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.VERSION': JSON.stringify(
process.env.VERSION || pkgJson.version
Expand All @@ -105,12 +113,6 @@ module.exports = (env = {}, { mode }) => {
// non TypeScript/JavaScript files (i.e. for font and CSS files).
new FileManagerPlugin({
onEnd: {
copy: [
{
source: 'src/examples/*.{html,html.media}',
destination: `${contentBase}/examples/`
}
],
delete: [
`${contentBase}/**/styles.js`,
`${contentBase}/**/styles.js`,
Expand All @@ -134,6 +136,22 @@ module.exports = (env = {}, { mode }) => {
}
},
{ test: /\.ejs$/, loader: 'ejs-loader' },
{
test: /\.html$/i,
// Don't transform HtmlWebpackPlugin generated file
exclude: /template\.html$/i,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: fileLoaderOutputPath
}
},
'extract-loader',
'html-loader'
]
},
{
test: /\.(css)$/,
use: [
Expand Down

0 comments on commit 363ab07

Please sign in to comment.