Compare commits

..

15 Commits

Author SHA1 Message Date
Igor Klopov
ca575bf0a6 Publish
- @now/next@0.0.85-canary.0
 - @now/node-server@0.4.27-canary.1
 - @now/node@0.4.29-canary.1
2019-01-29 19:09:01 +03:00
Igor Klopov
4c2e93ccef [now-node] bump ncc 2019-01-29 18:28:13 +03:00
paulogdm
4d6437d235 Fix broken error link (#175)
* Fix broken error link

* Added legacy mode error

Standard "Next.js" for all citations of Next.
Add "Legacy Mode" error.

* Update no serverless pages built doc

* Update doc on now/next legacy mode

* Add link after the error message
2019-01-28 19:05:02 +01:00
Igor Klopov
0d8058d062 Publish
- @now/node-server@0.4.27-canary.0
 - @now/node@0.4.29-canary.0
2019-01-27 21:58:47 +03:00
Igor Klopov
2b5cdfc0a7 [now-node] bump ncc 2019-01-27 15:27:00 +03:00
Igor Klopov
69a41f78fb Publish
- @now/build-utils@0.4.33-canary.1
2019-01-26 00:59:33 +03:00
Igor Klopov
a013d59d62 [build-utils] yarn in linux calls chown. mock it as well 2019-01-26 00:11:09 +03:00
Igor Klopov
173a29cfdb Publish
- @now/build-utils@0.4.33-canary.0
2019-01-25 02:51:46 +03:00
Igor Klopov
3f73451311 [build-utils] lint fixes 2019-01-25 00:55:32 +03:00
Igor Klopov
2fc706be43 [build-utils] make in-memory cache support git deps 2019-01-25 00:41:33 +03:00
Igor Klopov
0fb7eb6093 [build-utils] don't print download time of individual files 2019-01-24 18:44:10 +03:00
Igor Klopov
aa43c0bc87 [tests] consider now's 404 a case to retry 2019-01-23 18:43:55 +03:00
Igor Klopov
3c5925a6e3 [tests] print what failed page contains 2019-01-23 01:14:01 +03:00
Igor Klopov
9fc7b047f5 [tests] buildDelegate argument for testDeployment 2019-01-23 00:14:43 +03:00
Igor Klopov
ecae29457f Revert "[lerna] trying to set the order of package to publish"
This reverts commit 79251ad180.
2019-01-20 03:35:23 +03:00
13 changed files with 345 additions and 91 deletions

View File

@@ -0,0 +1,73 @@
# `@now/next` Legacy Mode
#### Why This Warning Occurred
`@now/next` has two modes: `legacy` and `serverless`. You will always want to use the `serverless` mode. `legacy` is to provide backwards compatibility with previous `@now/next` versions.
The differences:
Legacy:
- Minimal lambda size of `2.2Mb` (approximately)
- Forces `next@v7.0.2-canary.49` and `next-server@v7.0.2-canary.49`
- Forces all `dependencies` to be `devDependencies`
- Loads `next.config.js` on bootup, breaking sometimes when users didn't use `phases` to load files
- Used `next-server` which is the full Next.js server with routing etc.
- Runs `npm install`
- Runs `npm run now-build`
- Runs `npm install --production` after build
Serverless:
- Minimal lambda size of `49Kb` (approximately)
- Uses Next.js build targets (`target: 'serverless'`) in `next.config.js`. [documentation](https://github.com/zeit/next.js#summary)
- Does not make changes to your application dependencies
- Does not load `next.config.js` ([as per the serverless target documentation](https://github.com/zeit/next.js#summary))
- Runs `npm install`
- Runs `npm run now-build`
- Does not run `npm install --production` as the output from the build is all that's needed to bundle lambdas.
- No runtime dependencies, meaning smaller lambda functions
- Optimized for fast [cold start](https://zeit.co/blog/serverless-ssr#cold-start)
#### Possible Ways to Fix It
In order to create the smallest possible lambdas Next.js has to be configured to build for the `serverless` target.
1. Serverless Next.js requires Next.js 8 or later, currently this version is out on the `canary` release channel:
```
npm install next@canary
```
2. Add the `now-build` script to your `package.json`
```json
{
"scripts": {
"now-build": "next build"
},
}
```
3. Add `target: 'serverless'` to `next.config.js`
```js
module.exports = {
target: 'serverless'
// Other options are still valid
}
```
4. Optionally make sure the `"src"` in `"builds"` points to your application `package.json`
```js
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@now/next" }]
}
```
### Useful Links
- [Serverless target implementation](https://github.com/zeit/now-builders/pull/150)

View File

@@ -0,0 +1,43 @@
# `@now/next` No Serverless Pages Built
#### Why This Error Occurred
This error occurs when you have your application is not configured for Serverless Next.js build output.
#### Possible Ways to Fix It
In order to create the smallest possible lambdas Next.js has to be configured to build for the `serverless` target.
1. Serverless Next.js requires Next.js 8 or later, currently this version is out on the `canary` release channel:
```
npm install next@canary
```
2. Add the `now-build` script to your `package.json`
```json
{
"scripts": {
"now-build": "next build"
},
}
```
3. Add `target: 'serverless'` to `next.config.js`
```js
module.exports = {
target: 'serverless'
// Other options are still valid
}
```
4. Optionally make sure the `"src"` in `"builds"` points to your application `package.json`
```js
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@now/next" }]
}
```

View File

@@ -2,24 +2,7 @@
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/now-build-utils",
"packages/now-node-bridge",
"packages/now-php-bridge",
"packages/now-bash",
"packages/now-cgi",
"packages/now-go",
"packages/now-html-minifier",
"packages/now-lambda",
"packages/now-md",
"packages/now-mdx-deck",
"packages/now-next",
"packages/now-node",
"packages/now-node-server",
"packages/now-optipng",
"packages/now-php",
"packages/now-python",
"packages/now-static-build",
"packages/now-wordpress"
"packages/*"
],
"command": {
"publish": {

View File

@@ -49,7 +49,7 @@ class FileRef {
assert(url);
await semaToDownloadFromS3.acquire();
console.time(`downloading ${url}`);
// console.time(`downloading ${url}`);
try {
return await retry(
async () => {
@@ -66,7 +66,7 @@ class FileRef {
{ factor: 1, retries: 3 },
);
} finally {
console.timeEnd(`downloading ${url}`);
// console.timeEnd(`downloading ${url}`);
semaToDownloadFromS3.release();
}
}

View File

@@ -1,3 +1,5 @@
/* eslint-disable arrow-body-style,no-multi-assign,no-param-reassign */
const MemoryFileSystem = require('memory-fs');
const fs = require('fs');
const path = require('path');
@@ -19,76 +21,222 @@ function isInsideCachePath(filename) {
return !relative.startsWith('..');
}
const saveCreateWriteStream = fs.createWriteStream;
fs.createWriteStream = (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return saveCreateWriteStream.call(fs, ...args);
}
function replaceFn(name, newFnFactory) {
const prevFn = fs[name];
fs[name] = newFnFactory(prevFn);
}
vfs.mkdirpSync(path.dirname(filename));
fs.writeFileSync(filename, Buffer.alloc(0));
const stream = vfs.createWriteStream(...args);
stream.on('finish', () => {
setTimeout(() => {
stream.emit('close');
});
});
return stream;
};
const saveReadFile = fs.readFile;
fs.readFile = (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return saveReadFile.call(fs, ...args);
}
const callback = args[args.length - 1];
return vfs.readFile(...args.slice(0, -1), (error, result) => {
if (error) {
saveReadFile.call(fs, ...args);
return;
replaceFn('createWriteStream', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
callback(error, result);
});
};
const stream = vfs.createWriteStream(...args);
const saveCopyFile = fs.copyFile;
fs.copyFile = (...args) => {
const src = args[0];
const dest = args[1];
const callback = args[args.length - 1];
stream.on('finish', () => {
setTimeout(() => {
stream.emit('close');
});
});
if (isInsideCachePath(src) && !isInsideCachePath(dest)) {
const buffer = vfs.readFileSync(src);
return fs.writeFile(dest, buffer, callback);
}
setTimeout(() => {
stream.emit('open');
});
if (!isInsideCachePath(src) && isInsideCachePath(dest)) {
const buffer = fs.readFileSync(src);
return stream;
};
});
vfs.mkdirpSync(path.dirname(dest));
fs.writeFileSync(dest, Buffer.alloc(0));
return vfs.writeFile(dest, buffer, callback);
}
replaceFn('readFile', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
return saveCopyFile.call(fs, ...args);
};
const callback = args[args.length - 1];
return vfs.readFile(...args.slice(0, -1), (error, result) => {
if (error) {
return prevFn.call(fs, ...args);
}
const saveWriteFile = fs.writeFile;
fs.writeFile = (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return saveWriteFile.call(fs, ...args);
}
return callback(error, result);
});
};
});
vfs.mkdirpSync(path.dirname(filename));
fs.writeFileSync(filename, Buffer.alloc(0));
return vfs.writeFile(...args);
};
replaceFn('readdir', (prevFn) => {
return (...args) => {
const dirname = args[0];
if (!isInsideCachePath(dirname)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return prevFn.call(fs, dirname, (error, results) => {
if (error) {
results = [];
}
return vfs.readdir(dirname, (error2, results2) => {
if (error2) {
return callback(error2);
}
// eslint-disable-next-line no-restricted-syntax
for (const result2 of results2) {
if (!results.includes(result2)) {
results.push(result2);
}
}
return callback(error2, results);
});
});
};
});
replaceFn('stat', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return vfs.stat(...args.slice(0, -1), (error, result) => {
if (error) {
return prevFn.call(fs, ...args);
}
result.atime = result.mtime = new Date();
return callback(error, result);
});
};
});
replaceFn('lstat', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return vfs.stat(...args.slice(0, -1), (error, result) => {
if (error) {
return prevFn.call(fs, ...args);
}
result.atime = result.mtime = new Date();
return callback(error, result);
});
};
});
replaceFn('exists', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return vfs.exists(...args.slice(0, -1), (result) => {
if (!result) {
return prevFn.call(fs, ...args);
}
return callback(result);
});
};
});
replaceFn('copyFile', (prevFn) => {
return (...args) => {
const src = args[0];
const dest = args[1];
const callback = args[args.length - 1];
if (isInsideCachePath(src) && !isInsideCachePath(dest)) {
const buffer = vfs.readFileSync(src);
return fs.writeFile(dest, buffer, callback);
}
if (!isInsideCachePath(src) && isInsideCachePath(dest)) {
const buffer = fs.readFileSync(src);
return vfs.writeFile(dest, buffer, callback);
}
return prevFn.call(fs, ...args);
};
});
replaceFn('writeFile', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
return vfs.writeFile(...args);
};
});
replaceFn('mkdir', (prevFn) => {
return (...args) => {
const dirname = args[0];
if (!isInsideCachePath(dirname)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return prevFn.call(fs, dirname, (error) => {
if (error) {
return callback(error);
}
return vfs.mkdirp(dirname, callback);
});
};
});
replaceFn('utimes', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return setTimeout(callback, 0);
};
});
replaceFn('chmod', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return setTimeout(callback, 0);
};
});
replaceFn('chown', (prevFn) => {
return (...args) => {
const filename = args[0];
if (!isInsideCachePath(filename)) {
return prevFn.call(fs, ...args);
}
const callback = args[args.length - 1];
return setTimeout(callback, 0);
};
});
require(yarnPath);

View File

@@ -1,6 +1,6 @@
{
"name": "@now/build-utils",
"version": "0.4.32",
"version": "0.4.33-canary.1",
"license": "MIT",
"dependencies": {
"async-retry": "1.2.3",

View File

@@ -145,8 +145,9 @@ exports.build = async ({ files, workPath, entrypoint }) => {
}
console.warn(
"WARNING: your application is being deployed in @now/next's legacy mode.",
"WARNING: your application is being deployed in @now/next's legacy mode. http://err.sh/zeit/now-builders/now-next-legacy-mode",
);
console.log('normalizing package.json');
const packageJson = normalizePackageJson(pkg);
console.log('normalized package.json result: ', packageJson);

View File

@@ -1,6 +1,6 @@
{
"name": "@now/next",
"version": "0.0.84",
"version": "0.0.85-canary.0",
"license": "MIT",
"dependencies": {
"@now/node-bridge": "0.1.4",

View File

@@ -47,7 +47,7 @@ async function downloadInstallAndBundle(
'package.json': new FileBlob({
data: JSON.stringify({
dependencies: {
'@zeit/ncc': '0.11.0',
'@zeit/ncc': '0.13.0',
},
}),
}),

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node-server",
"version": "0.4.26",
"version": "0.4.27-canary.1",
"license": "MIT",
"dependencies": {
"@now/node-bridge": "^0.1.10",

View File

@@ -45,7 +45,7 @@ async function downloadInstallAndBundle(
'package.json': new FileBlob({
data: JSON.stringify({
dependencies: {
'@zeit/ncc': '0.11.0',
'@zeit/ncc': '0.13.0',
},
}),
}),

View File

@@ -1,6 +1,6 @@
{
"name": "@now/node",
"version": "0.4.28",
"version": "0.4.29-canary.1",
"license": "MIT",
"dependencies": {
"@now/node-bridge": "^0.1.10",

View File

@@ -22,7 +22,7 @@ async function packAndDeploy (builderPath) {
const RANDOMNESS_PLACEHOLDER_STRING = 'RANDOMNESS_PLACEHOLDER';
async function testDeployment ({ builderUrl, buildUtilsUrl }, fixturePath) {
async function testDeployment ({ builderUrl, buildUtilsUrl }, fixturePath, buildDelegate) {
console.log('testDeployment', fixturePath);
const globResult = await glob(`${fixturePath}/**`, { nodir: true });
const bodies = globResult.reduce((b, f) => {
@@ -63,6 +63,10 @@ async function testDeployment ({ builderUrl, buildUtilsUrl }, fixturePath) {
config.useBuildUtils = `https://${buildUtilsUrl}`;
}
}
if (buildDelegate) {
buildDelegate(build);
}
}
bodies['now.json'] = Buffer.from(JSON.stringify(nowJson));
@@ -84,7 +88,8 @@ async function testDeployment ({ builderUrl, buildUtilsUrl }, fixturePath) {
if (!text.includes(probe.mustContain)) {
await fs.writeFile(path.join(__dirname, 'failed-page.txt'), text);
throw new Error(
`Fetched page ${probeUrl} does not contain ${probe.mustContain}`
`Fetched page ${probeUrl} does not contain ${probe.mustContain}.`
+ ` Instead it contains ${text.slice(0, 60)}`
);
}
} else {
@@ -113,7 +118,8 @@ async function fetchDeploymentUrl (url, opts) {
for (let i = 0; i < 500; i += 1) {
const resp = await fetch(url, opts);
const text = await resp.text();
if (text && !text.includes('Join Free')) {
if (text && !text.includes('Join Free')
&& !text.includes('The page could not be found')) {
return text;
}