Skip to content

Commit

Permalink
[server] Allow specifying a basePath for a studio (#720)
Browse files Browse the repository at this point in the history
* [server] Allow specifying a basePath for a studio

* [default-layout] Resolve and use base path for studio if specified
  • Loading branch information
rexxars committed Apr 9, 2018
1 parent d1ff7c3 commit fa63389
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 29 deletions.
17 changes: 10 additions & 7 deletions packages/@sanity/base/src/components/Document.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import React from 'react'
import generateScriptLoader from '../util/generateScriptLoader'
import AppLoadingScreen from './AppLoadingScreen'

// todo: investigate this. Doesn't seem like NODE_ENV gets set on sanity.io
const ENV = process.env.NODE_ENV || 'development'

function assetUrl(staticPath, item) {
const isAbsolute = item.path.match(/^https?:\/\//)
if (isAbsolute) {
Expand All @@ -23,20 +20,24 @@ function assetUrl(staticPath, item) {
}

function Document(props) {
const basePath = props.basePath.replace(/\/+$/, '')
const staticPath = `${basePath}${props.staticPath}`

const stylesheets = props.stylesheets.map(item => (
<link key={item.path} rel="stylesheet" href={assetUrl(props.staticPath, item)} />
<link key={item.path} rel="stylesheet" href={assetUrl(staticPath, item)} />
))

const subresources = props.scripts.map(item => (
<link key={item.path} rel="subresource" href={assetUrl(props.staticPath, item)} />
<link key={item.path} rel="subresource" href={assetUrl(staticPath, item)} />
))

const scripts = props.scripts.map(item => assetUrl(props.staticPath, item))
const scripts = props.scripts.map(item => assetUrl(staticPath, item))
const scriptLoader = generateScriptLoader(scripts)

const favicons = props.favicons.map((item, index) => (
<link key={item.path + index} rel="icon" href={assetUrl(props.staticPath, item)} />
<link key={item.path} rel="icon" href={assetUrl(staticPath, item)} />
))

return (
<html>
<head>
Expand Down Expand Up @@ -66,6 +67,7 @@ const asset = PropTypes.shape({
})

Document.defaultProps = {
basePath: '',
charset: 'utf-8',
title: 'Sanity',
viewport: 'width=device-width, initial-scale=1',
Expand All @@ -77,6 +79,7 @@ Document.defaultProps = {
}

Document.propTypes = {
basePath: PropTypes.string,
charset: PropTypes.string,
title: PropTypes.string,
viewport: PropTypes.string,
Expand Down
5 changes: 3 additions & 2 deletions packages/@sanity/core/src/actions/build/buildStaticAssets.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export default async (args, context) => {
outputPath: path.join(outputDir, 'static'),
sourceMaps: flags['source-maps'],
skipMinify: !flags.minify,
profile: flags.profile
profile: flags.profile,
project: config.get('project')
}

await tryInitializePluginConfigs({workDir, output})
Expand Down Expand Up @@ -96,7 +97,7 @@ export default async (args, context) => {
const indexStart = Date.now()
spin = output.spinner('Building index document').start()
const doc = await getDocumentElement(
{...compilationConfig, hashes: chunkMap, project: config.get('project')},
{...compilationConfig, hashes: chunkMap},
{
scripts: ['vendor.bundle.js', 'app.bundle.js'].map(asset => {
const assetPath = absoluteMatch.test(asset) ? asset : `js/${asset}`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import React from 'react'
import DefaultLayout from './DefaultLayout'
import LoginWrapper from 'part:@sanity/base/login-wrapper?'
import {RouterProvider, RouteScope} from 'part:@sanity/base/router'
import NotFound from './NotFound'
import getOrderedTools from '../util/getOrderedTools'
import rootRouter from '../defaultLayoutRouter'
import * as urlStateStore from '../datastores/urlState'
import {RouterProvider} from 'part:@sanity/base/router'
import AppLoadingScreen from 'part:@sanity/base/app-loading-screen'
import * as urlStateStore from '../datastores/urlState'
import getOrderedTools from '../util/getOrderedTools'
import rootRouter, {maybeRedirectToBase} from '../defaultLayoutRouter'
import DefaultLayout from './DefaultLayout'
import NotFound from './NotFound'

const handleNavigate = urlStateStore.navigate

export default class DefaultLayoutContainer extends React.PureComponent {
state = {}

componentWillMount() {
maybeRedirectToBase()

this.urlStateSubscription = urlStateStore.state.subscribe({
next: event =>
this.setState({
Expand All @@ -26,10 +30,6 @@ export default class DefaultLayoutContainer extends React.PureComponent {
this.urlStateSubscription.unsubscribe()
}

handleNavigate(newUrl, options) {
urlStateStore.navigate(newUrl, options)
}

render() {
const {intent, urlState, isNotFound} = this.state
const tools = getOrderedTools()
Expand All @@ -48,7 +48,7 @@ export default class DefaultLayoutContainer extends React.PureComponent {
)

const router = (
<RouterProvider router={rootRouter} state={urlState} onNavigate={this.handleNavigate}>
<RouterProvider router={rootRouter} state={urlState} onNavigate={handleNavigate}>
{content}
</RouterProvider>
)
Expand Down
4 changes: 2 additions & 2 deletions packages/@sanity/default-layout/src/datastores/urlState.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import getOrderedTools from '../util/getOrderedTools'
import rootRouter from '../defaultLayoutRouter'
import locationStore from 'part:@sanity/base/location'
import getOrderedTools from '../util/getOrderedTools'
import reconfigureClient from '../util/reconfigureClient'
import {HAS_SPACES, CONFIGURED_SPACES} from '../util/spaces'
import rootRouter from '../defaultLayoutRouter'

function resolveUrlStateWithDefaultSpace(state) {
if (!HAS_SPACES || !state || state.space) {
Expand Down
19 changes: 17 additions & 2 deletions packages/@sanity/default-layout/src/defaultLayoutRouter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import {route} from 'part:@sanity/base/router'
import tools from 'all:part:@sanity/base/tool'
import {project} from 'config:sanity'
import {route} from 'part:@sanity/base/router'
import {CONFIGURED_SPACES, HAS_SPACES} from './util/spaces'

const basePath = ((project && project.basePath) || '').replace(/\/+$/, '')

const toolRoute = route('/:tool', toolParams => {
const foundTool = tools.find(current => current.name === toolParams.tool)
return foundTool ? route.scope(foundTool.name, '/', foundTool.router) : route('/')
Expand All @@ -12,4 +15,16 @@ const spaceRoute = route('/:space', params => {
return foundSpace ? toolRoute : route('/')
})

export default route('/', [route.intents('/intent'), HAS_SPACES ? spaceRoute : toolRoute])
const rootRouter = route(`${basePath}/`, [
route.intents('/intent'),
HAS_SPACES ? spaceRoute : toolRoute
])

export function maybeRedirectToBase() {
const redirectTo = rootRouter.getRedirectBase(location.pathname)
if (redirectTo) {
history.replaceState(null, null, redirectTo)
}
}

export default rootRouter
11 changes: 9 additions & 2 deletions packages/@sanity/server/src/baseServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react'
import ReactDOM from 'react-dom/server'
import requireUncached from 'require-uncached'
import {resolveParts} from '@sanity/resolver'
import getStaticBasePath from './util/getStaticBasePath'

const docPart = 'part:@sanity/base/document'
const initPart = 'part:@sanity/server/initializer'
Expand Down Expand Up @@ -40,11 +41,15 @@ export function getBaseServer() {

export function getDocumentElement({project, basePath, hashes}, props = {}) {
const assetHashes = hashes || {}

// Project filesystem base path
return getDocumentComponent(basePath).then(Document =>
React.createElement(
Document,
Object.assign(
{
// URL base path
basePath: (project && project.basePath) || '',
title: getTitle(project),
stylesheets: ['css/main.css'].map(item => assetify(item, assetHashes)),
scripts: ['js/vendor.bundle.js', 'js/app.bundle.js'].map(item =>
Expand All @@ -59,10 +64,12 @@ export function getDocumentElement({project, basePath, hashes}, props = {}) {

export function applyStaticRoutes(app, config = {}) {
const staticPath = config.staticPath || path.join(__dirname, '..', 'public')
app.use('/static', express.static(staticPath))
const staticBasePath = getStaticBasePath(config)

app.use(staticBasePath, express.static(staticPath))

app.get('*', (req, res) => {
if (req.url.indexOf('/static') === 0) {
if (req.url.startsWith(staticBasePath)) {
return res.status(404).send('File not found')
}

Expand Down
2 changes: 1 addition & 1 deletion packages/@sanity/server/src/configs/webpack.config.dev.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import webpack from 'webpack'
import getBaseConfig from './webpack.config'
import applyStaticLoaderFix from '../util/applyStaticLoaderFix'
import getBaseConfig from './webpack.config'

export default config => {
const baseConfig = getBaseConfig(config)
Expand Down
5 changes: 4 additions & 1 deletion packages/@sanity/server/src/configs/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import webpack from 'webpack'
import resolveFrom from 'resolve-from'
import webpackIntegration from '@sanity/webpack-integration/v3'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import getStaticBasePath from '../util/getStaticBasePath'

const resolve = mod => require.resolve(mod)

// eslint-disable-next-line complexity
export default (config = {}) => {
const staticPath = getStaticBasePath(config)
const env = config.env || 'development'
const wpIntegrationOptions = {basePath: config.basePath, env: config.env}
const basePath = config.basePath || process.cwd()
Expand Down Expand Up @@ -65,7 +68,7 @@ export default (config = {}) => {
output: {
path: config.outputPath || path.join(__dirname, '..', '..', 'dist'),
filename: 'js/[name].bundle.js',
publicPath: '/static/'
publicPath: `${staticPath}/`
},
resolve: {
alias: {
Expand Down
4 changes: 3 additions & 1 deletion packages/@sanity/server/src/devServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import {getBaseServer, applyStaticRoutes, callInitializers} from './baseServer'
import getWebpackDevConfig from './configs/webpack.config.dev'
import getStaticBasePath from './util/getStaticBasePath'

export default function getDevServer(config = {}) {
const staticPath = getStaticBasePath(config)
const app = getBaseServer(config)
const webpackConfig = config.webpack || getWebpackDevConfig(config)

// Serve an empty CSS file for the main stylesheet,
// as they are injected dynamically in development mode
app.get('/static/css/main.css', (req, res) => {
app.get(`${staticPath}/css/main.css`, (req, res) => {
res.set('Content-Type', 'text/css')
res.send()
})
Expand Down
10 changes: 10 additions & 0 deletions packages/@sanity/server/src/util/getStaticBasePath.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const getStaticBasePath = config => {
if (!config.project || !config.project.basePath) {
return '/static'
}

const basePath = ((config.project && config.project.basePath) || '').replace(/\/+$/, '')
return `${basePath}/static`
}

module.exports = getStaticBasePath

0 comments on commit fa63389

Please sign in to comment.