diff --git a/README.md b/README.md index cd38fb0d8..3026634b9 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ $ preact create --stylus Pre-install STYLUS support. [boolean] [default: false] --git Initialize version control using git. [boolean] [default: false] --no-install Disables installing of dependencies. [boolean] [default: false] + --yarn Installs dependencies with yarn. [boolean] [default: false] $ preact build @@ -136,6 +137,25 @@ $ preact serve ``` +### Templates + +### Full: + +- Preact Router Included +- Dynamic routes + +Demo + +### Simple: + +- Github API +Demo + +### Empty +- Boilerplate removed of styles and router + +Demo + ### Deploying ```sh diff --git a/examples/full/src/components/app.js b/examples/full/src/components/app.js index f3c4a849c..e091da7d7 100644 --- a/examples/full/src/components/app.js +++ b/examples/full/src/components/app.js @@ -4,8 +4,8 @@ import { Router } from 'preact-router'; import Header from './header'; import Home from '../routes/home'; import Profile from '../routes/profile'; -// import Home from 'async!./home'; -// import Profile from 'async!./profile'; +// import Home from 'async!../routes/home'; +// import Profile from 'async!../routes/profile'; export default class App extends Component { /** Gets fired when the route changes. diff --git a/package.json b/package.json index 22e64d9f1..83d2aab54 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "babel-preset-env": "^1.3.3", "babel-preset-stage-1": "^6.24.1", "babel-register": "^6.24.1", + "chalk": "^2.1.0", "copy-webpack-plugin": "^4.0.1", "cross-spawn-promise": "^0.10.1", "css-loader": "^0.28.4", diff --git a/src/lib/entry.js b/src/lib/entry.js index 83ec53052..420231a38 100644 --- a/src/lib/entry.js +++ b/src/lib/entry.js @@ -9,7 +9,7 @@ else if ('serviceWorker' in navigator && location.protocol === 'https:') { } -const interopDefault = m => m && m.default || m; +const interopDefault = m => m && m.default ? m.default : m; let app = interopDefault(require('preact-cli-entrypoint')); diff --git a/src/lib/webpack/prerender.js b/src/lib/webpack/prerender.js index 9b36c6c13..7cea2691a 100644 --- a/src/lib/webpack/prerender.js +++ b/src/lib/webpack/prerender.js @@ -40,35 +40,61 @@ export default function prerender(env, params) { const handlePrerenderError = (err, env, stack, entry) => { let errorMessage = err.toString(); let isReferenceError = errorMessage.startsWith('ReferenceError'); - let sourceMapContent = JSON.parse(fs.readFileSync(`${entry}.map`)); - let sourceMapConsumer = new SourceMapConsumer(sourceMapContent); - let position = sourceMapConsumer.originalPositionFor({ - line: stack.getLineNumber(), - column: stack.getColumnNumber() - }); + let methodName = stack.getMethodName(); + let sourceMapContent, position, sourcePath, sourceLines, sourceCodeHighlight; - position.source = position.source.replace('webpack://', '.'); + try { + sourceMapContent = JSON.parse(fs.readFileSync(`${entry}.map`)); + } catch (err) { + process.stderr.write(chalk.red(`Unable to read sourcemap: ${entry}.map\n`)); + } - let sourcePath = resolve(env.src, position.source); - let sourceLines = fs.readFileSync(sourcePath, 'utf-8').split('\n'); - let methodName = stack.getMethodName(); - let sourceCodeHighlight = ''; + if (sourceMapContent) { + let sourceMapConsumer = new SourceMapConsumer(sourceMapContent); + position = sourceMapConsumer.originalPositionFor({ + line: stack.getLineNumber(), + column: stack.getColumnNumber() + }); + + position.source = position.source.replace('webpack://', '.').replace(/^.*~\/((?:@[^/]+\/)?[^/]+)/, (s, name) => require.resolve(name).replace(/^(.*?\/node_modules\/(@[^/]+\/)?[^/]+)(\/.*)$/, '$1') ); - for (var i = -4; i <= 4; i++) { - let color = i === 0 ? chalk.red : chalk.yellow; - let line = position.line + i; - let sourceLine = sourceLines[line - 1]; - sourceCodeHighlight += sourceLine ? `${color(sourceLine)}\n` : ''; + sourcePath = resolve(env.src, position.source); + sourceLines; + try { + sourceLines = fs.readFileSync(sourcePath, 'utf-8').split('\n'); + } catch (err) { + try { + sourceLines = fs.readFileSync(require.resolve(position.source), 'utf-8').split('\n'); + } catch (err) { + process.stderr.write(chalk.red(`Unable to read file: ${sourcePath}\n`)); + } + // process.stderr.write(chalk.red(`Unable to read file: ${sourcePath}\n`)); + } + sourceCodeHighlight = ''; + + if (sourceLines) { + for (var i = -4; i <= 4; i++) { + let color = i === 0 ? chalk.red : chalk.yellow; + let line = position.line + i; + let sourceLine = sourceLines[line - 1]; + sourceCodeHighlight += sourceLine ? `${color(sourceLine)}\n` : ''; + } + } } process.stderr.write('\n'); process.stderr.write(chalk.red(`${errorMessage}\n`)); process.stderr.write(`method: ${methodName}\n`); - process.stderr.write(`at: ${sourcePath}:${position.line}:${position.column}\n`); - process.stderr.write('\n'); - process.stderr.write('Source code:\n\n'); - process.stderr.write(sourceCodeHighlight); - process.stderr.write('\n'); + if (sourceMapContent) { + process.stderr.write(`at: ${sourcePath}:${position.line}:${position.column}\n`); + process.stderr.write('\n'); + process.stderr.write('Source code:\n\n'); + process.stderr.write(sourceCodeHighlight); + process.stderr.write('\n'); + } + else { + process.stderr.write(stack.toString()+'\n'); + } process.stderr.write(`This ${isReferenceError ? 'is most likely' : 'could be'} caused by using DOM or Web APIs.\n`); process.stderr.write(`Pre-render runs in node and has no access to globals available in browsers.\n\n`); process.stderr.write(`Consider wrapping code producing error in: 'if (typeof window !== "undefined") { ... }'\n`); diff --git a/src/lib/webpack/webpack-client-config.js b/src/lib/webpack/webpack-client-config.js index 194498b92..c46dc2e67 100644 --- a/src/lib/webpack/webpack-client-config.js +++ b/src/lib/webpack/webpack-client-config.js @@ -221,7 +221,11 @@ const htmlPlugin = (config, src) => { excludeAssets: [/(bundle|polyfills)(\..*)?\.js$/], config, ssr(params) { - return config.prerender ? prerender({ dest: config.dest, src }, { ...params, url }) : ''; + return config.prerender ? prerender({ + dest: config.dest, + src, + cwd: config.cwd + }, { ...params, url }) : ''; } }); const pages = readJson(resolve(config.cwd, config.prerenderUrls || '')) || [{ url: "/" }];