werkzeug
v0.0.15
Published
compiles ts, coffee, sass/scss, less/ stylus and packs browser ready bundles
Downloads
70
Maintainers
Readme
werkzeug
Is the german word for "tool".
And is the compiler and packer for my projects.
It does a little bit of the stuff, webpack and co. does for you.
It is limited in its skills but easy to use and fast.
What werkzeug does:
- compiles typescript, coffee, sass/scss, less and stylus
- can copy all other assets
- packs your compiled code (if you use commonjs style modules) to bundles for use in browsers
- supports asynchronous chunks (angular 2/webpack style promisses)
- serves your stuff
- watches for changes and compiles and packs incremental
- creates source maps for all compiled files and the bundles
- lints typescript
- has little support for angular projects
- and you can require json, css, html and txt files in your code, which will be inlined as strings
And what it can't do:
no pre or post processor or loader system, you can't pimp werkzeug (werkzeug will dispatch events soon, so you can utilize it by your own build process)
the packer has no es2015 or es6 support (except for node_modules, but slow and only as fallback) (the ts compiler still can compile to es6)
no build or release process exists (i use googles closure compiler to minify my bundles) (optimizing your project can be very special to your project and i like to keep werkzeug simple)
no live reload or browser sync (maybe i will implement this later)
currently no AoT compiling for angular 2 (maybe i will work on this)
no tree shaking (but i am interested)
Usage
npm install -g werkzeug
# or, if you want to be up to date
git clone https://github.com/jarends/werkzeug.git
cd werkzeug
npm install
npm link
# copy the default config
wz -i
# compile, copy and pack once
wz
# start the watcher, which also starts the server
wz -w
# example project angular 2 tour of heroes
# with werkzeug as build tool
git clone https://github.com/jarends/angular2-tour-of-heroes-wz.git
cd angular2-tour-of-heroes-wz
npm install
npm start # or wz -w
Config
werkzeug looks for a '.werkzeug' file in the current directory.
The file can be a json file or a js, which exports a config object.
~~If no file was found, werkzeug looks in your user home for a config.~~
With 'wz -i' you can copy the default config to your project.
This is the default config with all implemented options:
('assets' is the copying process)
in: './src'
out: './.wz.tmp'
options:
includeExternalMaps: false # include source maps from node_modules
fffMaps: false # inline source maps (fixes a firefox bug)
server:
enabled: true
port: 3001 # if in use or blocked, the next free port is used
coffee:
in: null
out: null
enabled: true
ts:
in: null
out: null
enabled: true
ngTool: true # enable angular 2 magic
sass:
in: null
out: null
globals: [] # files, which will compile, if others change
enabled: true
less:
in: null
out: null
enabled: true
styl:
in: null
out: null
enabled: true
assets:
in: null
out: null
enabled: true
tslint:
ignoreInitial: true # no linting on startup
enabled: true
packer:
nga: false # run ng-annotate (angular 1)
bigChunks: false # pack multi 'requireds' into chunks instead of bundles
chunks: './chunk_' # file name prefix for chunk files
loaderPrefix: 'es6-promise!' # prefix for requiring chunks
uglify: false # uglify all packed files -> makes initial packing verry slow
enabled: true
packages: [] # in/out config for packing bundles -> relative to global in/out
# The simplest config, which compiles all files from './src' to './dist'
# and packs the file './dist/main.js' (maybe compiled from './src/main.ts')
# and all its required files to the bundle './dist/main.bundle.js'.
# The entry bundle must be the first (important!).
out: './dist'
packer:
packages: [
in: './main.js',
out: './main.bundle.js'
]
# Chunks will be handled automaticly if you use
chunkPromise = require('es6-promise!./my-external-module')()
# or for a specific export (required by angular 2)
chunkPromise = require('es6-promise!./my-external-module')('MyClass')
# and then
chunkPromise.then((result) -> console.log 'myExternalModuleOrClass: ', result)
# If you specify more than the entry bundle, you have to require all subsequent entry files.
# Otherwise they won't be activated.
# You also have to place src nodes for each bundle in your index.html
Some Details
ts and tslint
werkzeug comes with a default tsconfig.json and tslint.json.
However, it also tries to read this files from your project directory so you can override the default settings.
The creation and handling of source maps is a little bit tricky. That's why the following ts compiler options can't be overridden:
options.sourceMap # always true (will change, if source map creation can be turned off)
options.rootDir # always the ts 'in' dir
options.outDir # always the ts 'out' dir
options.sourceRoot # always the relative path from 'out' to 'in'
options.baseUrl # always the path to werkzeugs node_modules
packer
The packer works on the compiled js files and parses all required dependencies.
Currently only es5 commonjs style modules are supported.
The parsing is done by a simple reqex for 'require' and that's the reason for a MAJOR BUG i still haven't fixed (for performance reasons):
If you have comments (single or multiline) in your code with unused but valid 'require' statements, this 'requires' are still parsed and the packer tries to import the dependencies.
The packer doesn't handle es6 files in your project, but he compiles required es6 node_modules with babel to not break your dependencies.
The babel process isn't optimized and can slow down the whole packaging process if he is used excessively and the es6 detection is a little bit weird.
angular 2
Angular 2 has the ability to load templates and styles at runtime. The angular-cli, which, by the way, does a very good job and i strongly recommend to use it, replaces the 'templateUrl' and 'styleUrls' properties in the @Component decorator with the related 'template' and 'styles' properties and embeds the files.
I personally don't like this behaviour, because, if i want to embed my templates i can use 'template' instead of 'templateUrl', so i actively made a decision
and angular-cli ignores my decision (that's a little bit impolite).
However, to not break projects, which expect this behaviour, i decided to enable the same impoliteness in werkzeug, but configurable ;-)
The second angular 2 magic is: replacing the routers 'loadChildren' list with the appropriate chunk promises.
possible bugs
as i mentioned above: 'require' statements, which are commented out, are still parsed by the packer and the dependencies are packed
individual input and output directories per compiler aren't tested very well (especially in relation to source maps)
input and output pointing to the same directory isn't tested very well (especially for the asset process) (can corrupt your project, be careful!)
the asset process itself can behave a little bit weird in relation to what he copies
the logic for when the linting happens must be reviewed and behaves sometimes strange
the whole process can stuck in a loop (this can happen with errors in ts files and relies on the linting strangeness)
(never tested on windows, sorry)
Motivation and Todos
When i started working with angular 2, SystemJS and webpack i was a little bit frustrated about the complexity of configuration and the time i spent to start new projects.
The only thing i wanted to do was coding.
The second point was the rapidly changing angular development in the release phase and the delay of webpack changes to manage all the new requirements.
I wanted a little bit more control by my self, so i decided to build my own tool (it's a little bit maniac, looking at the multitude of other good tools, i know).
werkzeug is currently not really meant to be ready. I stopped the development and started to use it so i can see, what more i have to do.
There are still some ideas i want to implement.
This are my current TODOS:
#TODO: add multiple in and out paths!!!
#TODO: add post processors (like autoprefixer)!!!
#TODO: fix errors for empty project!!!
#TODO: fix errors for multiple instances in the same project
#TODO: set ts.noEmitOnError = true and merge packer errors back to compiler errors???
#TODO: make source maps optional!!!
#TODO: enable cli flag for different configs, maybe run configs concurrently
#TODO: watch current wz config and restart app on change
#TODO: remember TREESHAKING for the build process (if it ever comes)???
License
werkzeug is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.