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: "/" }];