Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add development build feature to the razzle build script (on master) #1693

Merged
merged 4 commits into from Aug 21, 2021

Conversation

silviubogan
Copy link
Contributor

@silviubogan silviubogan commented Aug 21, 2021

so that the razzle build script can produce a development build (which is sometimes useful for testing) using just a parameter --node-env=development

see #1289

Tasks

  • the modified build script also seems to start a background process that still writes to the terminal after appearantly exiting the process
  • I replaced "nodeEnv === 'production' ? 'prod' : 'dev'," with "prod", as it was before and I don't know why it is was a mistake (?) but it solves this problem:

it produces the development build but it also starts it which seems wrong to me, although I put --noninteractive and when removing the --node-env=development it produces the production build without starting it

  • I think I still have to make some sort of test for the improved --node-env option, am I right?

@fivethreeo Please let me know if you can help me with any of these tasks/questions listed above. Any feedback is appreciated. Thanks.

so that the razzle build script can produce a development build
which is sometimes useful for testing using just a parameter
--node-env=development

see jaredpalmer#1289
@vercel
Copy link

vercel bot commented Aug 21, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/jared/razzle/Dfd8hegKwM1hzaAA9aCP2T2ru6Tu
✅ Preview: https://razzle-git-fork-silviubogan-build-for-development-jared.vercel.app

that should remain local
@silviubogan
Copy link
Contributor Author

@fivethreeo For some reason the command npm run build in the new example does not produce a dev build (I remember that, before this new PR, it produced a dev build). Now I have no idea how to make it produce a dev build.

> razzle build --node-env=development

If you have issues with css make sure postcss resolves to v8.2.4.
See: https://razzlejs.org/getting-started#common-issues

CssMinimizerPlugin currently uses clean-css,
we will switch to cssnano once it supports postcss v8.2.4.

Compiling client default build...

Client default build compiled with warnings


asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  static/js/client.14b40ff8.js (272 KiB)

entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  client (272 KiB)
      static/css/client.aeb8fc1a.css
      static/js/client.14b40ff8.js


webpack performance recommendations: 
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/


Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

File sizes after gzip:

  83.42 KB  build/public/static/js/client.14b40ff8.js
  185 B     build/assets.json
  185 B     build/public/static/css/client.aeb8fc1a.css

Compiling server default build...

Compiled server default build successfully.

The output files contain obfuscated and minified code.

@fivethreeo
Copy link
Collaborator

Oh, you mean dev in that way. Actually that has to be done for each case because razzle decides how to configure webpack by the 'dev' 'prod' string. So using 'dev' will start the server and add react refresh and hot reloading code. So we have to change that in createConfigAsync but IS_DEV and IS_PROD vars decide what plugins to add in big if blocks and also decides what mode webpack runs in and assumes we run in razzle start. So what we need to do is to check actual env and set a different webpack mode, set the dev tool, change splitchunks, disable terser, maybe change something in the define plugin options. This is sort of a legacy from early razzle and will need to be addressed better in the next major version. But we can fix it for now by brute force without changing the razzle api.

@fivethreeo
Copy link
Collaborator

'prod' and 'dev' should be 'start' and 'build' really, but backwards compatibility is a must until 5.0

@fivethreeo
Copy link
Collaborator

I think I need to do this actually, needs lots of internal knowledge. But I can pull this one after I fix it 😀

@silviubogan
Copy link
Contributor Author

@fivethreeo

I think I need to do this actually, needs lots of internal knowledge. But I can pull this one after I fix it grinning

Thanks. If you need some help from a beginner like me, please let me know, especially if my help can speed things up. I am restlessly waiting for the new version that has this feature.

@fivethreeo fivethreeo marked this pull request as ready for review August 21, 2021 15:30
@fivethreeo fivethreeo merged commit 29eb51e into jaredpalmer:master Aug 21, 2021
@fivethreeo
Copy link
Collaborator

Are you able to try out the master branch?

@silviubogan
Copy link
Contributor Author

Are you able to try out the master branch?

I think that in about 30 minutes I'll start an attempt. Thank you very much for your work!

@silviubogan
Copy link
Contributor Author

@fivethreeo How can I use npm link with the Razzle monorepo to reference the razzle package in it? Should I try to use Yalc?

@silviubogan
Copy link
Contributor Author

@fivethreeo

$ NODE_ENV=development npx tsc -b && NODE_ENV=development npx razzle build --noninteractive --node-env=development

ERROR  Unexpected error

TypeError: Cannot set property 'noEmitOnErrors' of undefined
    at /some/path/to/razzle/monorepo/packages/razzle/config/createConfigAsync.js:971:46

@fivethreeo
Copy link
Collaborator

Pushed a fix, retry now

@silviubogan
Copy link
Contributor Author

Pushed a fix, retry now

I ran git pull.

image

@fivethreeo
Copy link
Collaborator

Using yalc?

@silviubogan
Copy link
Contributor Author

Using npm link. Should I try with Yalc?

@fivethreeo
Copy link
Collaborator

Don't think you got the changes somehow, yalc works too.

@silviubogan
Copy link
Contributor Author

@fivethreeo Yes, you are right.

image

@fivethreeo
Copy link
Collaborator

@silviubogan
Copy link
Contributor Author

The razzle repo is up-to-date, but npm link does not work. When I run npm link razzle inside the directory of the app I am working on I get:

/path/to/app/directory/node_modules/razzle -> /home/silviub/.nvm/versions/node/v12.22.5/lib/node_modules/razzle -> /path/to/razzle/monorepo/packages/razzle

Does this look right?

@fivethreeo
Copy link
Collaborator

Not sure, I only use yarn.

@fivethreeo
Copy link
Collaborator

try rerunning npm install?

@silviubogan
Copy link
Contributor Author

I solved with Yalc and now I get:

TypeError: ManifestPlugin is not a constructor
    at /path/to/my/app/node_modules/razzle/config/createConfigAsync.js:744:9

@fivethreeo
Copy link
Collaborator

Ah, sorry, I missed one ;)

@silviubogan
Copy link
Contributor Author

The masked log is here. Good night!

@fivethreeo
Copy link
Collaborator

@silviubogan
Copy link
Contributor Author

When deploying, it requests the JS and CSS bundles from localhost instead of the domain name/IP address. It almost works. I think it has to do with the environment variable called RAZZLE_ASSETS_MANIFEST which is set by Razzle.

@silviubogan
Copy link
Contributor Author

silviubogan commented Aug 22, 2021

It seems to me that on the remote server RAZZLE_ASSETS_MANIFEST is set to /local/path/to/my/app/build/assets.json.

@fivethreeo
Copy link
Collaborator

Fixed

@fivethreeo
Copy link
Collaborator

@silviubogan
Copy link
Contributor Author

When running NODE_ENV=development npx tsc -b && NODE_ENV=development npx razzle build --noninteractive --node-env=development I get, after successful client build,

Failed to compile server default build.

[
  {
    moduleIdentifier: '/path/to/my/app/node_modules/razzle/config/babel-loader/razzle-babel-loader.js??razzle-babel-loader!/path/to/my/app/src/server/index.tsx',
    moduleName: './src/server/index.tsx',
    loc: '95:11-54',
    message: "Module not found: Error: Can't resolve 'build/assets.json' in '/path/to/my/app/src/server'",
    moduleId: './src/server/index.tsx',
    moduleTrace: [ [Object] ],
    details: "resolve 'build/assets.json' in '/path/to/my/app/src/server'\n" +
      '  Parsed request is a module\n' +
      '  using description file: /path/to/my/app/package.json (relative path: ./src/server)\n' +
      '    resolve as module\n' +
      "      /path/to/my/app/src/server/node_modules doesn't exist or is not a directory\n" +
      "      /path/to/my/app/src/node_modules doesn't exist or is not a directory\n" +
      '      looking for modules in /path/to/my/app/node_modules\n' +
      "        /path/to/my/app/node_modules/build doesn't exist\n" +
      '      looking for modules in /run/media/silviub/T7-Touch/Lucru/node_modules\n' +
      "        /run/media/silviub/T7-Touch/Lucru/node_modules/build doesn't exist\n" +
      "      /run/media/silviub/T7-Touch/node_modules doesn't exist or is not a directory\n" +
      "      /run/media/silviub/node_modules doesn't exist or is not a directory\n" +
      "      /run/media/node_modules doesn't exist or is not a directory\n" +
      "      /run/node_modules doesn't exist or is not a directory\n" +
      "      /node_modules doesn't exist or is not a directory\n" +
      '      looking for modules in /path/to/my/app/node_modules\n' +
      "        /path/to/my/app/node_modules/build doesn't exist\n" +
      '      looking for modules in /path/to/my/app/src\n' +
      "        /path/to/my/app/src/build doesn't exist",
    stack: "ModuleNotFoundError: Module not found: Error: Can't resolve 'build/assets.json' in '/path/to/my/app/src/server'\n" +
      '    at /path/to/my/app/node_modules/webpack/lib/Compilation.js:1773:28\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:811:13\n' +
      '    at eval (eval at create (/path/to/my/app/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:8:1)\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:286:22\n' +
      '    at eval (eval at create (/path/to/my/app/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:442:22\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:124:11\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:673:25\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:882:8\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:1002:5\n' +
      '    at /path/to/my/app/node_modules/neo-async/async.js:6883:13\n' +
      '    at /path/to/my/app/node_modules/webpack/lib/NormalModuleFactory.js:985:45\n' +
      '    at finishWithoutResolve (/path/to/my/app/node_modules/enhanced-resolve/lib/Resolver.js:296:11)\n' +
      '    at /path/to/my/app/node_modules/enhanced-resolve/lib/Resolver.js:362:15\n' +
      '    at /path/to/my/app/node_modules/enhanced-resolve/lib/Resolver.js:410:5\n' +
      '    at eval (eval at create (/path/to/my/app/node_modules/enhanced-resolve/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)'
  }
]

Thanks.

@silviubogan
Copy link
Contributor Author

@fivethreeo The normal (production) build throws the same error.

@fivethreeo
Copy link
Collaborator

fivethreeo commented Aug 22, 2021 via email

@fivethreeo
Copy link
Collaborator

I checked it, loaded by webpack and inlined. I will just undo the relative path :)

@fivethreeo
Copy link
Collaborator

fivethreeo commented Aug 22, 2021

By the way

You can just run

yarn try-example with-development-build

In the razzle monorepo

Then

cd example
yarn build

If you change something in razzle run

yarn updateyalc

In the example dir

#1695

@silviubogan
Copy link
Contributor Author

Now the remote server serves the JS bundle from e.g. http://localhost:3005/static/js/client.f7b441b5.js (similar issue) which is unavailable. But the local production build works well.

@silviubogan
Copy link
Contributor Author

The local development build also does not work. The JS and CSS bundles are requested from similar URLs but the response from the server is SSR. I want to take another look at with-webpack-public-path to see if I'm missing some functionality in the SSR server.

@fivethreeo
Copy link
Collaborator

What is the env vars in remote?

@fivethreeo
Copy link
Collaborator

Also does the remote run start:prod

@silviubogan
Copy link
Contributor Author

@fivethreeo

What is the env vars in remote?

I have this part of code in the server:

let assets: any;

const syncLoadAssets = () => {
  fs.writeFileSync("env-vars.json", JSON.stringify(process.env, null, 2));
  assets = require(process.env.RAZZLE_ASSETS_MANIFEST!);
};
syncLoadAssets();

that produces the following masked output in env-vars.json:

{
  "USER": "root",
  "SSH_CLIENT": "<some numbers>",
  "SSH_AGENT_PID": "<some numeric ID>",
  "XDG_SESSION_TYPE": "tty",
  "SHLVL": "3",
  "MOTD_SHOWN": "pam",
  "HOME": "/root",
  "SSH_TTY": "/dev/pts/0",
  "nvm_current_version": "v12.22.5",
  "DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/0/bus",
  "FORCE_COLOR": "2",
  "LOGNAME": "root",
  "_": "/root/.local/share/nvm/v12.22.5/bin/npx",
  "PUBLIC_PATH": "http://<some IP address>:3005/",
  "XDG_SESSION_CLASS": "user",
  "TERM": "screen.xterm-256color",
  "XDG_SESSION_ID": "<some numeric ID>",
  "PATH": "/root/path/to/my/app/on/remote/node_modules/.bin:/root/.local/share/nvm/v12.22.5/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin",
  "SSH_ENV": "/root/.ssh/environment",
  "XDG_RUNTIME_DIR": "/run/user/0",
  "LANG": "C.UTF-8",
  "STY": "<screen session identifier>",
  "SSH_AUTH_SOCK": "<irrelevant>",
  "SHELL": "/usr/bin/fish",
  "WINDOW": "0",
  "PWD": "</absolute/path/to/app/dir/in/remote/server>",
  "SSH_CONNECTION": "<some numbers here>",
  "TERMCAP": "SC|screen.xterm-256color|VT 100/ANSI X3.64 virtual terminal:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:li#41:co#140:am:xn:xv:LP:sr=\\EM:al=\\E[L:AL=\\E[%dL:cs=\\E[%i%d;%dr:dl=\\E[M:DL=\\E[%dM:dc=\\E[P:DC=\\E[%dP:im=\\E[4h:ei=\\E[4l:mi:IC=\\E[%d@:ks=\\E[?1h\\E=:ke=\\E[?1l\\E>:vi=\\E[?25l:ve=\\E[34h\\E[?25h:vs=\\E[34l:ti=\\E[?1049h:te=\\E[?1049l:us=\\E[4m:ue=\\E[24m:so=\\E[3m:se=\\E[23m:mb=\\E[5m:md=\\E[1m:mh=\\E[2m:mr=\\E[7m:me=\\E[m:ms:Co#8:pa#64:AF=\\E[3%dm:AB=\\E[4%dm:op=\\E[39;49m:AX:vb=\\Eg:G0:as=\\E(0:ae=\\E(B:ac=\\140\\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:po=\\E[5i:pf=\\E[4i:Km=\\E[M:k0=\\E[10~:k1=\\EOP:k2=\\EOQ:k3=\\EOR:k4=\\EOS:k5=\\E[15~:k6=\\E[17~:k7=\\E[18~:k8=\\E[19~:k9=\\E[20~:k;=\\E[21~:F1=\\E[23~:F2=\\E[24~:kB=\\E[Z:kh=\\E[1~:@1=\\E[1~:kH=\\E[4~:@7=\\E[4~:kN=\\E[6~:kP=\\E[5~:kI=\\E[2~:kD=\\E[3~:ku=\\EOA:kd=\\EOB:kr=\\EOC:kl=\\EOD:km:",
  "PUBLIC_URL": "http://<SOME IP ADDRESS>:3005/",
  "NODE_ENV": "production",
  "PORT": "3005",
  "CONNECTION_STRING": "<MongoDB connection string>",
  "ABS_PATH_TO_CA": "<Some path to a certificate file>"
}

Also does the remote run start:prod

The development bundle of the app on the remote server is started with:

PUBLIC_URL=http://<some IP address>:3005/ PUBLIC_PATH=http://<the same IP address>:3005/ NODE_ENV=production npx concurrently "node build/server.js" "node build/wsserver.js"

@fivethreeo
Copy link
Collaborator

If you look in build/server.js what does webpack_public_path say?

@silviubogan
Copy link
Contributor Author

image

@silviubogan
Copy link
Contributor Author

In build/public/static/js/client.d41c432c.js I have

image

@fivethreeo
Copy link
Collaborator

Try searching for localhost

@silviubogan
Copy link
Contributor Author

In the client JS bundle:

image

@silviubogan
Copy link
Contributor Author

In .env.local, which is manually loaded in the server, I have:

PORT=3005
PUBLIC_URL=http://localhost:3005/
PUBLIC_PATH=http://localhost:3005/
CONNECTION_STRING=<some MongoDB connection string>

@silviubogan
Copy link
Contributor Author

Not .env.local but .env.production should be loaded. I check NODE_ENV and based on that, in the server, I load either .env.local or .env.production.

@silviubogan
Copy link
Contributor Author

Does Razzle somehow load .env.local automatically?

@fivethreeo
Copy link
Collaborator

@fivethreeo
Copy link
Collaborator

During build that is

@fivethreeo
Copy link
Collaborator

PUBLIC_PATH is a build time var only, that is what causes the confusion, use your own var in deployment.

@silviubogan
Copy link
Contributor Author

I've changed the .env.local file's name and correctly set the env vars at build time and, when I access the home page of the app, SSR runs, but the JS bundle request returns SSR HTML too.

image

@silviubogan
Copy link
Contributor Author

@fivethreeo I had to set RAZZLE_PUBLIC_DIR before build time and now this new feature works very very well! Thank you for your work! You are awesome!

@fivethreeo
Copy link
Collaborator

I often do process.env.PUBLIC_DIR||process.env.RAZZLE_PUBLIC_DIR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants