When trying to build and deploy to now
, everything seems to build fine but at the end of the build process I get the following error:
Unable to import module 'now__launcher': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/task/next.config.js:2:51)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
Steps to reproduce the behavior, please provide code snippets or a repository:
https://github.com/lorenseanstewart/next-blog-starter
npm i
from the rootnow
now logs <url-provided-by-deploy>
This project to deploy without errors.
Moving this issue to the now-cli repo.
_Because this is the first result in google, and there is no link to the other issue, I will leave the fix I found here:_
The issue comes due to trying to run bundling work during the production serving phase of next (details here), such as @zeit/next-css
, @zeit/next-sass
, or @zeit/next-typescript
.
The fix is to only run those during the build phase of running next:
next.config.js
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {} // We're never in "production server" phase when in development mode
: !process.env.NOW_REGION
? require('next/constants') // Get values from `next` package when building locally
: require('next-server/constants'); // Get values from `next-server` package when building on now v2
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
const withCSS = require('@zeit/next-css');
return withCSS();
};
_Update_: Still not working? See this comment below
_Update 2_: Added extra conditional so it builds locally too.
_Update 3_: Corrected to use NOW_REGION
over NOW
on now v2.
For anyone stumbling into this, the issue is not necessarily related to next-css.
I got the same problem having withBundleAnalyzer(...)
returned from next.config.js.
Wrapping it the same way as described above helped.
@jesstelford thanks but I am still getting the error
by the way it should be next/constants
my code below but errors keep comming
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === "development" ? {} : require("next/constants");
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
return withPlugins(
[
withCss,
withSass
],
{
webpack(config, { isServer }) {
if (ANALYZE) {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: "server",
analyzerPort: isServer ? 8888 : 8889,
openAnalyzer: true
})
);
config.plugins.push(new WebpackBundleSizeAnalyzerPlugin("stats.txt"));
}
config.module.rules.push({
test: /\.(png|svg|eot|otf|ttf|woff|woff2)$/,
use: {
loader: "url-loader",
options: {
limit: 100000,
publicPath: "./",
outputPath: "static/",
name: "[name].[ext]"
}
}
});
// config.plugins.push(new AntdScssThemePlugin(path.join(__dirname, "assets", "theme.scss")));
return config;
}
// generateBuildId: async () => {
// const fromGit = await nextBuildId({ dir: __dirname });
// return fromGit.id;
// },
}
);
};
+1 Same probem as efleurine
@efleurine @TLevesque Where is withCss
/ withSass
getting defined? It's not included in your example.
You must make sure you only require('@zeit/next-css')
_after_ you've checked if (phase === PHASE_PRODUCTION_SERVER)
.
ie;
Don't do this:
// โ Don't put this here
const withCSS = require('@zeit/next-css');
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
return withCSS();
};
Do this
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
// โ
Put the require call here.
const withCSS = require('@zeit/next-css');
return withCSS();
};
_Update_: added conditional so it will work when building locally too.
_Update 2_: Corrected to use NOW_REGION
over NOW
on now v2.
Thank you very much @jesstelford for your help!
@efleurine Just for info, apparently next-compose-plugins package + next-sass doesn't work with this pattern suggested by jesstelford : https://github.com/cyrilwanner/next-compose-plugins/issues/13
Here is the content of the next.config.js file which is working properly on now v2, for a complex example with several plugins from Nextjs and its community, like dotenv, next-images, @zeit/next-sass, webpack-bundle-size-analyzer, @zeit/next-bundle-analyzer and next-plugin-transpile-modules.
Here is the repo if it can help someone: https://github.com/TLevesque/platform-trials
@jesstelford, just to make sure, can you confirm that this is the correct syntax to use in term of best practices:
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === "development"
? {}
: require("next-server/constants");
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
const sass = require("@zeit/next-sass");
const images = require("next-images");
require("dotenv").config();
const path = require("path");
const Dotenv = require("dotenv-webpack");
const withBundleAnalyzer = require("@zeit/next-bundle-analyzer");
const {
WebpackBundleSizeAnalyzerPlugin
} = require("webpack-bundle-size-analyzer");
const withTM = require("next-plugin-transpile-modules");
const { ANALYZE } = process.env;
return withBundleAnalyzer(
images(
sass(
withTM({
analyzeServer: ["server", "both"].includes(
process.env.BUNDLE_ANALYZE
),
analyzeBrowser: ["browser", "both"].includes(
process.env.BUNDLE_ANALYZE
),
bundleAnalyzerConfig: {
server: {
analyzerMode: "static",
reportFilename: "../bundles/server.html"
},
browser: {
analyzerMode: "static",
reportFilename: "./bundles/client.html"
}
},
transpileModules: ["lodash-es"],
webpack: config => {
config.plugins = config.plugins || [];
config.plugins = [
...config.plugins,
new Dotenv({
path: path.join(__dirname, ".env"),
systemvars: true
})
];
if (ANALYZE) {
config.plugins.push(
new WebpackBundleSizeAnalyzerPlugin("stats.txt")
);
}
config.externals = Array.isArray(config.externals)
? config.externals.map(fn =>
typeof fn === "function"
? (context, request, callback) => {
if (request === "lodash-es") {
return callback(null, "commonjs lodash");
}
return fn(context, request, callback);
}
: fn
)
: config.externals;
return config;
}
})
)
)
);
};
It looks good to me, and if it works, then I'd say you're good to go ๐
@jesstelford thanks for these suggestions. However, I'm still getting this issue even after the fixes above. You can see my repo here https://github.com/media-chain/916-frontend. I've tried to strip it back as much as I can.
@humet Be sure to use require('next-server/constants')
, not require('next/constants')
.
@jesstelford, I'm getting this error at building locally:
Cannot find module 'next-server/constants'
Deployment works fine though.
Ah, looks like that module doesn't exist locally.
I guess there should be a check for if its running on now's servers or not. I think there's NOW
env var we could use?
Does this work both locally and when deploying for you?
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
_Edit_: updated the condition to work locally.
_Edit 2_: Corrected to use NOW_REGION
over NOW
on now v2.
Ah, looks like that module doesn't exist locally.
I guess there should be a check for if its running on now's servers or not. I think there's
NOW
env var we could use?Does this work both locally and when deploying for you?
const { PHASE_PRODUCTION_SERVER } = process.env.NODE_ENV === 'development' ? {} : !!process.env.NOW ? require('next/constants') : require('next-server/constants');
Nope, same error on local building.
Edit: Ok, looks like the condition was wrong. This works:
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW
? require('next/constants')
: require('next-server/constants');
Hi
Unfortunately, I still get that error.
My config is:
```js
require('dotenv').config();
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW
? require('next/constants')
: require('next-server/constants');
const config = {
publicRuntimeConfig: {
endpoint: process.env.ENDPOINT,
username: process.env.USERNAME,
password: process.env.PASSWORD
}
};
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
return config;
}
const withCSS = require('@zeit/next-css');
return withCSS(config);
};
@alexedev what's in your .env
file? I have a hunch NODE_ENV
is being overwritten. It should be development
locally, and production
for deployment to now.
@alexedev Your code has problem in this line
return withCSS(config);
The config
is undefined
.
@jesstelford can you guess what's wrong with this next.config.js
?
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW
? require('next/constants')
: require('next-server/constants');
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
console.log('---- PROD ----');
return {};
}
// โ
Put the require call here.
const withSass = require('@zeit/next-sass');
console.log('---- DEV ----');
return withSass(defaultConfig);
};
@jesstelford The problem on local build is resolved but I still get a 502 in Now.
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW
? require('next/constants')
: require('next-server/constants');
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
// โ
Put the require call here.
const withCSS = require('@zeit/next-css');
return withCSS();
};
Unable to import module 'now__launcher': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/task/next.config.js:5:9)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
502: An error occurred with your deployment
Code: NO_STATUS_CODE_FROM_LAMBDA
(more)
@alexedev, @carlesandres, @MaksKoseda:
๐ฑ My apologies, I gave you a bum steer; the env var we should be checking against is NOW_REGION
(not NOW
). I've updated the examples above, and copied here for posterity:
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION // โน๏ธ Must be `NOW_REGION`, not `NOW` (my bad)
? require('next/constants')
: require('next-server/constants');
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production.
return {};
}
const withCSS = require('@zeit/next-css');
return withCSS();
};
The only change is:
? {}
- : !process.env.NOW
+ : !process.env.NOW_REGION
? require('next/constants')
Just opened #5846 to discuss/address this issue
@revskill10 it is defined in the upper scope
@jesstelford just:
ENDPOINT=
USERNAME=
PASSWORD=
they are handled with no problem on localhost (next
command for development and next build && next start
for production ). basically, the next.config.js is valid on localhost in both cases.
And NODE_ENV
is not overwritten in any way.
BTW thank you for the correction: process.env.NOW_REGION
is exposed while using now
(13.0.0-canary.24) for deployment. but the deployment fails anyway (I get same error code as @MaksKoseda ). It happens even when only 'next-server/constants'
is used on production without checking if it is now
deployment or not, like const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development' ? {} : require('next-server/constants');
I console logged these envs as well as phase
and PHASE_PRODUCTION_SERVER
variables and In zeit.co deployment output I get this:
$ next build --lambdas
process.env.NOW_REGION: bru1
process.env.NOW: undefined
process.env.NOW_URL: undefined
phase: phase-production-build
PHASE_PRODUCTION_SERVER: phase-production-server
I understand that phase
value is OK because it is a build phase indeed but I do not see it console logged again in the output to have value phase-production-server
. So in the end phase === PHASE_PRODUCTION_SERVER
condition is never true
(to double-check it I added a dummy console.log('USED PROD CONFIG')
in the code block that should be run if the condition is true and this string is never logged in zeit.co output)`
When I run next start
locally then the values are equal:
phase: phase-production-server
PHASE_PRODUCTION_SERVER: phase-production-server
Is there any similar step as next start
during now
deployment?
PS I suppose this doc should be corrected https://zeit.co/docs/v2/deployments/environment-variables-and-secrets/#built-in-variables (both NOW
and NOW_URL
are undefined in now
deployment)
@jesstelford that change:
? {}
- : !process.env.NOW
+ : !process.env.NOW_REGION
? require('next/constants')
fixed my problem with deploying to now v2. Thanks!
@alexedev I discovered the same thing with environment variables and not seeing expected output.
My guess is the console.log during build _is_ happening, but it's not being stored in the logs, so we don't see it. As confirmed by @carlesandres, the latest magic incantation works for both local and now v2.
And, err, in case anyone thinks otherwise; I don't work for @zeit, or on the now
platform. I'm just someone who came up against this issue and wanted to share my knowledge on how to get past it.
Thank you everyone who has been thoughtful and helpful while we worked it out together โค๏ธ
Hopefully a more official fix will come from @timneutkens in #5846 ๐
@timneutkens Will it ever be possible to run @zeit/next-sass
with now 2? How can lambda support binary module?
Afaik it already works, you just have to change next.config.js as outlined by https://github.com/zeit/next.js/issues/5750#issuecomment-445575468
I always get 404 responses when I try this
EDIT: never mind, it was because I was trying to data read files with readFileSync. It turns out next on now 2.0 doesn't support these.
well, I finally resolved my problem...
Lambda failed (error 502) because I relied on dotenv
package to take env values from .env
file
but two things went wrong:
.env
is ignored by now
require('dotenv').config();
is called in now environment (I did not understand the reason yet).Instead, env values should be referenced in now.json
the values are becoming available automatically with no need to call dotenv
and such
see https://zeit.co/docs/v2/deployments/environment-variables-and-secrets/
my now.json
looks like
{
"version": 2,
"builds": [{ "src": "next.config.js", "use": "@now/next" }],
"env": {
"ENDPOINT": "@endpoint",
"USERNAME": "@username",
"PASSWORD": "@password"
}
}
So here is how the fixed next.config.js
looks like:
if (!process.env.NOW_REGION) {
// if deploying with now-ci env values are taken not from .env but from now.json
// https://zeit.co/docs/v2/deployments/environment-variables-and-secrets/
// now deployment breaks if dotenv used
require('dotenv').config();
}
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
const config = {
publicRuntimeConfig: {
endpoint: process.env.ENDPOINT,
username: process.env.USERNAME,
password: process.env.PASSWORD
}
};
module.exports = (phase, { defaultConfig }) => {
if (phase === PHASE_PRODUCTION_SERVER) {
// Config used to run in production
return config;
}
const withCSS = require('@zeit/next-css');
return withCSS(config);
};
this can get a bit more readable by assigning process.env.NOW_REGION
to a constant but I wanted to be explicit
If you have any other suggestions for more eloquent fix, please let me know
An alternative to dotenv
as @alexedev describes is dotenv-webpack
:
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
module.exports = phase => {
if (phase === PHASE_PRODUCTION_SERVER) {
return {};
}
const DotEnv = require('dotenv-webpack');
return {
webpack: config => {
config.plugins.push(new DotEnv());
return config;
}
};
};
Then you can use process.env.*
directly as it will be read from .env
and replaced during build.
@alexedev, @carlesandres, @MaksKoseda:
๐ฑ My apologies, I gave you a bum steer; the env var we should be checking against isNOW_REGION
(notNOW
). I've updated the examples above, and copied here for posterity:const { PHASE_PRODUCTION_SERVER } = process.env.NODE_ENV === 'development' ? {} : !process.env.NOW_REGION // โน๏ธ Must be `NOW_REGION`, not `NOW` (my bad) ? require('next/constants') : require('next-server/constants'); module.exports = (phase, { defaultConfig }) => { if (phase === PHASE_PRODUCTION_SERVER) { // Config used to run in production. return {}; } const withCSS = require('@zeit/next-css'); return withCSS(); };
The only change is:
? {} - : !process.env.NOW + : !process.env.NOW_REGION ? require('next/constants')
This fixed the issue for me! Thanks @jesstelford
@jesstelford OMG I finally got this to work thanks to you!. Thanks a lot man!
@TLevesque Btw, I got mine to work with next-compose-plugins
with:
const {PHASE_PRODUCTION_SERVER} =
process.env.NODE_ENV === "development"
? {} // We're never in "production server" phase when in development mode
: !process.env.NOW_REGION
? require("next/constants") // Get values from `next` package when building locally
: require("next-server/constants"); // Get values from `next-server` package when building on now v2
const nextConfig = {
webpack: config => {
// Fixes npm packages that depend on `fs` module
config.node = {
fs: "empty"
};
config.module.rules = config.module.rules.map(rule => {
if (rule.loader === "babel-loader") {
rule.options.cacheDirectory = false;
}
return rule;
});
return config;
}
};
module.exports = (phase, {defaultConfig}) => {
if (phase === PHASE_PRODUCTION_SERVER) {
return {};
}
//const withImages = require("next-images");
const withSass = require("@zeit/next-sass");
const {withPlugins} = require("next-compose-plugins");
return withPlugins([[withSass]], nextConfig)(phase, defaultConfig);
};
Worth noting, that considering this issue, the documentation here is incorrect then:
https://www.npmjs.com/package/@zeit/next-typescript
An alternative to
dotenv
as @alexedev describes isdotenv-webpack
:const { PHASE_PRODUCTION_SERVER } = process.env.NODE_ENV === 'development' ? {} : !process.env.NOW_REGION ? require('next/constants') : require('next-server/constants'); module.exports = phase => { if (phase === PHASE_PRODUCTION_SERVER) { return {}; } const DotEnv = require('dotenv-webpack'); return { webpack: config => { config.plugins.push(new DotEnv()); return config; } }; };
Then you can use
process.env.*
directly as it will be read from.env
and replaced during build.
This is the exact same problem I had when trying to directly implement with-dotenv
from the Next.JS examples.
Thank you @webpro, @alexedev and @jesstelford !!! It worked perfectly. You don't know how many hours I've wasted in this and how many more I would've wasted without you guys. Thanks!
Nothing on this thread seems to be working out.
I can run locally, but @webpro 's solution to use Webpack dotenv doesn't seem to get my Now deployment working:
const { PHASE_PRODUCTION_SERVER } =
process.env.NODE_ENV === 'development'
? {}
: !process.env.NOW_REGION
? require('next/constants')
: require('next-server/constants');
module.exports = phase => {
if (phase === PHASE_PRODUCTION_SERVER) {
return {};
}
const DotEnv = require('dotenv-webpack');
return {
webpack: config => {
config.plugins.push(new DotEnv());
return config;
}
};
};
@jesstelford 's original solution does not work either.
The problem seems to be that I can't access my environment variables with process.env.VARIABLE_NAME
when in production. Has anyone else had success with a now-deployed app that uses process.env with secrets successfully?
My small repo that I'm struggling with is here: https://github.com/mulholio/onboard
@mulholio I'm using it in https://github.com/webpro/bookstore
@webpro do you have any secret variables (as in Now secrets)? I'm starting to think that might be some of my problem.
@mulholio No
Everyone in this issue will want to upgrade their application to this: https://github.com/zeit/now-examples/pull/214
package.json
+ don't drop yarn.lock/package-lock.json anymore. We don't add next-server anymore etc. More details here: https://github.com/zeit/now-builders/pull/150
@timneutkens can you please provide details on how to use that with with-typescript and with-css, as most people in this issue ran into problems because of a mandatory useage of one of the with-* helpers. Are such helpers no longer necessary?
I'm not sure what the issue is ๐ค As per zeit/now-examples#214:
{
"version": 2,
"builds": [
{"src": "package.json", "use": "@now/next"}
]
}
yarn add next@canary
module.exports = {
target: 'serverless'
}
Or when you're using plugins:
const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript({
target: 'serverless'
})
now-build
script to package.json:{
"scripts": {
"now-build": "next build"
}
}
You can read more about the serverless target here: https://github.com/zeit/now-builders/pull/150
And here: https://github.com/zeit/next.js/pull/5927
Then run now
. You can verify if you're running the new serverless mode by checking /_logs
for MODE: serverless
. If it says MODE: legacy
it means your package.json has a Next.js version that doesn't support target: 'serverless'
as per the specification here: https://github.com/zeit/now-builders/pull/150
@timneutkens ok great, so none of the workarounds above that we had to do are necessary anymore! Fantastic! Thanks you for your hard work
Exactly ๐ No workarounds and a lot of benefits ๐
@timneutkens
After adding the changes you suggested I see:
Error: Cannot find module '<path>/src/.next/server/static/OJLfDlRyija6wxm_8Ywn4/pages/_document'
And it turns out that folder is OJLfDlRyija6wxm_8Ywn4
in static.
(Also it is lambda package)
Any idea what I may be doing wrong?
but it's missing _document
file in that path
so my question would be what am I doing wrong?
Are you deploying to Now or your own hosting?
AWS lambda
Please read https://github.com/zeit/next.js/pull/5927. It sounds like you're deploying a Next.js server
, instead you should deploy the standalone functions that come out of the Next.js serverless target build.
Example working migration: https://github.com/webpro/bookstore/commit/f5da96599095aa6b8d80330ab5b7ff7f2e2ae6fb per @timneutkens guide. Thanks, Tim!
As it is explained here no custom server can be used with lambdas deployed with now v2. Does it mean next-routes cannot be used? What about dynamic pages with clean urls?
Most helpful comment
_Because this is the first result in google, and there is no link to the other issue, I will leave the fix I found here:_
The issue comes due to trying to run bundling work during the production serving phase of next (details here), such as
@zeit/next-css
,@zeit/next-sass
, or@zeit/next-typescript
.The fix is to only run those during the build phase of running next:
next.config.js
_Update_: Still not working? See this comment below
_Update 2_: Added extra conditional so it builds locally too.
_Update 3_: Corrected to use
NOW_REGION
overNOW
on now v2.