Skip to content

Rebuild speed and style workflows (feedback) #2956

Closed
@sasxa

Description

@sasxa

I just finished rewriting my old gulp build tasks to work with CLI. Results are... interesting :) #1980

CLI

c:\project>ng s
** NG Live Development Server is running on http://localhost:4200. **
17976ms building modules
...
Time: 26259ms
...
webpack: bundle is now VALID.

webpack: bundle is now INVALID.
Time: 10887ms

webpack: bundle is now INVALID.
Time: 6893ms

webpack: bundle is now INVALID.
Time: 5964ms

webpack: bundle is now INVALID.
Time: 9595ms

Gulp

c:\project>gulp
[00:47:08] Requiring external module ts-node/register
[00:47:15] Starting 'watch'...
[brSync] Watching files...
[brSync] Access URLs:
       Local: http://localhost:3000
[00:47:18] Finished 'serve' after 2.14 s

[00:48:42] Starting 'ts'...
[00:48:43] all files 16.27 kB
[00:48:43] Finished 'ts' after 194 ms

[00:49:33] Starting 'ts'...
[00:49:33] Starting 'styl'...
[00:49:33] Finished 'styl' after 171 ms
[00:49:33] Finished 'ts' after 200 ms

[00:50:17] Starting 'ts'...
[00:50:17] Finished 'ts' after 57 ms

[00:51:52] Starting 'ts'...
[00:51:52] Starting 'styl'...
[00:51:52] Finished 'styl' after 274 ms
[00:51:52] all files 15.83 kB
[00:51:52] Finished 'ts' after 308 ms

1
2

Webpack is,, of course, much better at optimizing assets, while gulp can be optimized for really fast incremental builds. At this time I didn't do anything with vendor files, I'm just serving them with BrowserSync directly from node_modules - that's why there are so many requests and why load times are high. I also didn't bother with code splitting, AoT and other stuff Webpack and CLI already do - I just want fast dev builds; I'm definitely gonna use CLI for that stuff.

This is done at the same time in two terminal windows - first running Gulp watch and serving files with BrowserSync, second running webpack-dev-server. If you want to try it yourself, you can find full logs and files I used here: (Gist). Build works with CLI project with some modification - for index.html and system.config.js I used files from docs/quickstart and modified them to fit my project. Only other thing needed to make it work is to remove import './polyfills.ts'; from 'src/main.ts`.

OK, now the reason I'm writing this is to share what I learned while trying to make this work, hopefully it will be useful and help improve CLI.

Styling


  • It would be nice if workflow with style pre-processors was easier: I'm using stylus and I couldn't find any options to include some shared files and mixins. In my project I created src/styles/ folder where all my .styl files are and I'm importing them from src/styles.styl with @import 'styles/defaults'. I also have src/styles/variables.styl where I @import "C:/.library/styl/mixins.styl"... It would be nice if we had access to stylus to extend it, like I'm doing:
.pipe(__.stylus({
    include: [
      path.resolve(PATH.root, 'src'),
      path.resolve(PATH.root, 'src', 'styles'),
      path.resolve(PATH.lib, 'styl')]
  }))
  • Same goes for other modules (html-minifier, autoprefixer, csso...). Since I couldn't setup paths where stylus looks for imports, I had to use @import '../../styles/variables' in my component styles, which I had to remove in order to process styles with Gulp file.replace(/@import\s+'(?:\.\.\/)+/gmi, '@import \'').

  • Another nice feature would be to have separate file for inline styles, that would be injected directly in <head> while the rest are loaded normally, via <link>. I think I saw something like this in early versions with --mobile and/or --universal... I saw some improvements with styles workflows on master branch, nice! Hope to see more (;

Dev builds


  • Concerning module resolution, I'm using "compilerOptions.baseUrl": "." path mapping so I can use import {...} from 'app/core/service' instead of import {...} from '../../../../app/core/service' in my components. Might be useful to be there by default? I saw some issues/PRs/commits with import {...} from '@shared' - not sure what's the status of that, but aliasing app root is really useful for me.

  • While building my gulp tasks I noticed that rebuilding typescript files seams to be main reason for high rebuild times. I chose to use settings that give me fastest results

  • I'm not bundling files, my components/services/modules etc. are in separate files. This allows me to utilize gulp's caching, so it will only process changed files:

  return gulp.src(files, {
    since: gulp.lastRun('ts')
  })
  • I used "isolatedModules": true, compiler option to make this work. TypeScript now Unconditionally emit imports for unresolved files., which also speed things up.

  • I'm injecting everything in js file - templates, styles, sourcemaps. It's not ideal, and sourcemaps are not precise, but I usually know what I'm doing, so most of the time I can find errors quickly. And if not, I can always use different options to track down bugs. With 50-250ms rebuild times I work differently then when I have to wait 5-15s... For production builds and various optimizations I really don't mind waiting 30-90s.

  • While I don't think something like this should be default option for CLI, perhaps there are some things you could turn off, or do differently to speed things up. Maybe provide some flag to turn off some safety checks, not bundle everything each time and such. I'm not that familiar with webpack to offer any suggestions, but maybe something I mentioned can help (;

Finally, just to mention the dreadful systemjs... The way I have structured my modules and components is really, really painful to setup with systemjs. In fact, making it work took me almost as long as everything else... It was the reason why I was happy CLI switched to webpack. Working with CLI is soo much easier. If (or when!) CLI was 10x faster I would gladly forget everything about systemjs. Forever (:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions