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

Do not uglify builds when running start-dev #858

Merged
merged 5 commits into from
Jan 23, 2017
Merged

Conversation

xPaw
Copy link
Member

@xPaw xPaw commented Dec 30, 2016

Tweaks bundle paths (client vs client/js) to not confuse sourcemaps as much. Disables uglifyjs plugin when running with --watch. Also reduces production built file size a little more.

@xPaw xPaw added this to the 2.2.0 milestone Dec 30, 2016
@@ -2,11 +2,12 @@

const webpack = require("webpack");
const path = require("path");
const isWatch = process.argv.includes("--watch");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be relying on NODE_ENV instead?

"build:webpack": "webpack",
"watch": "webpack -w",
"build:webpack": "webpack -p",
"watch": "webpack -d --watch",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For whoever is wondering, node_modules/.bin/webpack -h says:

  -d    shortcut for --debug --devtool sourcemap --output-pathinfo
  -p    shortcut for --optimize-minimize

I see this as unofficial development/production flags, am I correct?
If so, it's a bit confusing that build:webpack implies production and watch implies development. I know I sometimes use npm run build:webpack when I just want a single build without a FS watch.

IMO (but MO is fairly Webpack-inexperienced 😅), I think we should have the commands be environment-independent, and the configuration files behave differently depending on the environment (or select different files depending on environment, if the configurations are too disjoint).
Is that stupid?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the record:

  • --devtool sourcemap is already specified in our Webpack config.
  • --optimize-minimize is the same as the UglifyJsPlugin in our Webpack config.
  • --debug enables debug mode of loaders, which is something we probably do not want on development env at all time.
  • If I understand --output-pathinfo, it is of little interest.

@astorije
Copy link
Member

astorije commented Jan 2, 2017

Playing a bit with the current state, we definitely cannot have configurations differ solely on build:webpack vs. watch. When you check out a branch and run npm install, this (at least until #737 gets addressed) this assumes prod.

I think our best bet is to rely on NODE_ENV to be production (which is also set when using --production).

@xPaw
Copy link
Member Author

xPaw commented Jan 3, 2017

I wanted to use env at first, but setting it in script and making it crossplatform is not easy.

@astorije
Copy link
Member

astorije commented Jan 3, 2017

I don't think we have a choice though. Could use https://www.npmjs.com/package/cross-env for cross-platform in scripts?

@xPaw
Copy link
Member Author

xPaw commented Jan 3, 2017 via email

@astorije
Copy link
Member

astorije commented Jan 4, 2017

You mean to emulate cross-env?

Anyway, it doesn't really matter I think, since it's mostly NODE_ENV=production npm install which will be useful. The rest should assume default NODE_ENV or use the one being set.

Copy link
Member

@astorije astorije left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cf. discussions in comment.

@astorije astorije added Type: Bug Issues that report and PRs that solve any defects that cause unexpected behaviors. priority and removed priority labels Jan 4, 2017
]
};

if (!isWatch) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use the node_env directly from here if you wanted to filter it from production and development build.

process.env.NODE_ENV

@leaexplores
Copy link

Using the process.env.NODE_ENV to determine what to build or not is how most of the webpack-built project does. I left a comment in the code if we want to include the uglify plugin only when in production (NODE_ENV == PRODUCTION)...

@astorije astorije force-pushed the xpaw/tweak-webpack branch from 7ba8b3a to f34f34e Compare January 7, 2017 23:06
"build:webpack": "webpack",
"watch": "webpack -w",
"build:webpack": "webpack -p",
"watch": "webpack -d --watch",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for the record:

  • --devtool sourcemap is already specified in our Webpack config.
  • --optimize-minimize is the same as the UglifyJsPlugin in our Webpack config.
  • --debug enables debug mode of loaders, which is something we probably do not want on development env at all time.
  • If I understand --output-pathinfo, it is of little interest.


cache:
directories:
- ~/.npm

before_script:
- NODE_ENV=$BUILD_ENV npm run build

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works fine when BUILD_ENV is not defined, which is the case outside of that included combination.

Copy link
Member

@AlMcKinlay AlMcKinlay Jan 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if it isn't defined, does it just ignore that, and default to not production?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, if BUILD_ENV isn't defined, it runs NODE_ENV= npm run build which is similar as setting an empty environment (i.e. a not production).

@astorije
Copy link
Member

astorije commented Jan 8, 2017

Alright, spent a looot of time on this, between reading docs and GitHub threads for Webpack, npm, etc. I believe this PR puts us in an optimal state regarding recent introduction of Webpack.

This PR resolves the first 2 items of #857 (comment).

Posting here my commit message details + extra info:

1. Use Webpack configuration based on NODE_ENV instead of watch/no-watch

Also, move the DedupePlugin to the prod-specific section. Webpack doc itself recommends to not run this outside of production.

Note that this currently breaks cross-OS support of npm run build. This will be fixed in a latter commit. This was temporary and on purpose to not mix the unrelated commits of Webpack-for-production and no-npm run build-on-npm install. It's fixed by the next commit.

This commit addresses my comments made in this PR. Non-cross-OS character of this commit is the reason why the next commits are part of this PR.

2. Make and document npm run build now a mandatory step of the install/build setup

This has several reasons, benefits and consequences:

  • When running on root (which is not recommended anyway), npm run build was already necessary.
  • This allows to not use the prepublish hook, whose behavior is going to change in npm v5 and again in npm v6.
  • This allows to create both production and development builds when running from source.
  • It makes npm run build compatible with Windows again for development environments (lost in previous commit).
  • It uses the prepublishOnly hook added in npm v4. Since this hook is not available prior to that, deployment to npm from Travis has to be done on the Node.js v7 environment.

This fixes #737.

3. Add an extra Travis CI job to make sure production build succeeds and passes tests

This only adds one extra job to the build (which still runs all its jobs concurrently, so build time does not increase) to make sure what we deploy or will is actually correct.

This is highly desirable since we now produce 2 different files in development/testing and production.

4. Add a basic check for bundled application when starting the server

Note that this will not detect if the client application was built with an old version of the repo.

This partially addresses #737 (comment), but a naive check is better than no checks!

"test": "npm-run-all -c test:* lint",
"test:mocha": "mocha",
"lint": "npm-run-all -c lint:*",
"lint:js": "eslint .",
"lint:css": "stylelint \"**/*.css\"",
"prepublish": "npm run build"
"prepublishOnly": "NODE_ENV=production npm run build"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't execute on Windows, fyi.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be fine, because we should only ever be publishing from travis.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What @YaManicKill said. You can still run npm run build on Windows, and if someone ever needs to deploy from Windows, which should only happen in case something goes wrong on Travis CI, one can always change prepublishOnly so a Windows-friendly command temporarily.

@astorije
Copy link
Member

astorije commented Jan 8, 2017 via email

@@ -18,6 +18,11 @@ var authFunction = localAuth;
module.exports = function() {
manager = new ClientManager();

if (!fs.existsSync("client/js/bundle.js")) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideas on how we would check hashes to tell the file is out of date?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solutions I can think of are not ideal. For example, I don't know if this is possible without forcing people committing on the client to include such marker in their PR.

Either way, can we do this in a latter PR please? This PR should not go further than what it currently does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's look into this in another one. I guess you could do it by the first line of the bundle being a version number or git hash or something.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would probably move this block into index.js. I'm not sure it belongs in server.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll move it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, I've tried to move it to index.js and I'd definitely keep it where it is: index.js doesn't have access to log at the moment (probably not a big deal but still) but way more importantly, it's blocking -h, the list subcommand, etc.

Let's keep it that way for now and we can improve that later.

path: path.resolve(__dirname, "client/js"),
filename: "bundle.js",
path: path.resolve(__dirname, "client"),
filename: "[name]",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually with webpack, you'll be using the compilation hash that can easily be appended at build.

You would configure webpack to output like so inside the webpack config...

module.exports = {
...
	output: {
		path: path.join(__dirname, 'dist'),
		pathinfo: (env !== 'production'),
		filename: 'app-[hash:6].js'
       }
...
}

This will output a app-rand6c.js (app- 6 random characters as i've requested 6). filename in the output folder.

From there you could include it easily in the server.js

xPaw and others added 2 commits January 10, 2017 13:07
Also, move the `DedupePlugin` to the prod-specific section. [Webpack doc](https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin) itself recommends to not run this outside of production.

Note that this currently breaks cross-OS support of `npm run build`. This will be fixed in a latter commit.
@astorije
Copy link
Member

@thelounge/maintainers, yes, no, anyone? :)
v2.2.0 is sooo close... !

@AlMcKinlay
Copy link
Member

@astorije Sorry, didn't realise you guys had stopped messing around with this PR :-P I sort of phased out the notifications. I'll take a look now.

Copy link
Member

@AlMcKinlay AlMcKinlay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looks good. I've not tested this, but assuming 1 of you have.

Are we 100% sure that the bundle is included in the npm publish?


cache:
directories:
- ~/.npm

before_script:
- NODE_ENV=$BUILD_ENV npm run build

Copy link
Member

@AlMcKinlay AlMcKinlay Jan 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, if it isn't defined, does it just ignore that, and default to not production?

"test": "npm-run-all -c test:* lint",
"test:mocha": "mocha",
"lint": "npm-run-all -c lint:*",
"lint:js": "eslint .",
"lint:css": "stylelint \"**/*.css\"",
"prepublish": "npm run build"
"prepublishOnly": "NODE_ENV=production npm run build"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should be fine, because we should only ever be publishing from travis.

@@ -18,6 +18,11 @@ var authFunction = localAuth;
module.exports = function() {
manager = new ClientManager();

if (!fs.existsSync("client/js/bundle.js")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's look into this in another one. I guess you could do it by the first line of the bundle being a version number or git hash or something.

@xPaw
Copy link
Member Author

xPaw commented Jan 14, 2017

Fyi, building from git will most likely not minify (as you have to explicitly set node env to prod). The changes are fine for now.

@@ -6,11 +6,17 @@ node_js:

matrix:
fast_finish: true
include:
- node_js: 7 # Version used to deploy to npm registry
env: BUILD_ENV=production

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't set node env directly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, otherwise devDependencies aren't installed. The rationale is: run npm install in non-production environment to be able to build, but build for production environments at release time.

- While it is the most recent codebase, this is not production-ready!
- It is not recommended to run this as root. However, if you decide to do so,
you will have to run `npm run build`.
⚠️ Run at your own risk. It is also not recommended to run this as root.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the mention that all development happens in master and it may not be stable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

…/build setup

This has several reasons, benefits and consequences:

- When running on root (which is not recommended anyway), `npm run build` was already necessary.
- This allows to not use the `prepublish` hook, whose behavior is going to change in npm v5 and again in npm v6.
- This allows to create both production and development builds when running from source.
- It makes `npm run build` compatible with Windows again for development environments (lost in previous commit).
- It uses the `prepublishOnly` hook added in npm v4. Since this hook is not available prior to that, deployment to npm from Travis has to be done on the Node.js v7 environment.
Note that this will not detect if the client application was built with an old version of the repo.
@astorije
Copy link
Member

Alright, I believe (well, I hope 😅) this one is finally good to go. @xPaw, are you happy with it?

@xPaw
Copy link
Member Author

xPaw commented Jan 23, 2017

👍

@AlMcKinlay AlMcKinlay merged commit 91ae814 into master Jan 23, 2017
@AlMcKinlay
Copy link
Member

Well, I'll merge, then.

@AlMcKinlay AlMcKinlay deleted the xpaw/tweak-webpack branch January 23, 2017 10:42
@astorije astorije mentioned this pull request Feb 12, 2017
matburnham pushed a commit to matburnham/lounge that referenced this pull request Sep 6, 2017
Do not uglify builds when running start-dev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Issues that report and PRs that solve any defects that cause unexpected behaviors.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants