1 | # Tarima
|
2 |
|
3 | [![Build Status](https://travis-ci.org/tacoss/tarima.png?branch=next)](https://travis-ci.org/tacoss/tarima)
|
4 | [![NPM version](https://badge.fury.io/js/tarima.png)](http://badge.fury.io/js/tarima)
|
5 | [![Coverage Status](https://codecov.io/github/tacoss/tarima/coverage.svg?branch=next)](https://codecov.io/github/tacoss/tarima)
|
6 | [![Known Vulnerabilities](https://snyk.io/test/npm/tarima/badge.svg)](https://snyk.io/test/npm/tarima)
|
7 |
|
8 | ![Tarima](tarima.png)
|
9 |
|
10 | ```bash
|
11 | $ npm install tarima --save-dev
|
12 | ```
|
13 |
|
14 | **Tarima** is a pre-processing tool based on filename extensions.
|
15 |
|
16 | ## 1.0 - How it works
|
17 |
|
18 | Lets say `view.js.pug` will produce a pre-compiled Pug template, which is rendered from pug, etc.
|
19 |
|
20 | If you omit the `js` extension then `view.pug` will produce markup, since `html` is the default extension for the Pug engine.
|
21 |
|
22 | > You can add as many extensions you want, whilst the output is valid input for the next renderer in the chain.
|
23 |
|
24 | ### 1.1 - Parsing
|
25 |
|
26 | `load(filename, options)` — Shortcut for calling `parse()` from reading the given filename with `fs.readFileSync()`.
|
27 |
|
28 | See below. ↓
|
29 |
|
30 | `parse(filename, source, options)` — Primary method for turning the given source into a abstract representation of itself.
|
31 |
|
32 | > The filename is required but _not required_ to exists, is just a hint for tarima to understand what to do with it.
|
33 |
|
34 | The resulting object will contain a `render()` callback and `params` object, respectively:
|
35 |
|
36 | - `view.render(locals, callback)` — Performs the transpilation on the given source, producing a new source.
|
37 |
|
38 | - `view.params` — An object like:
|
39 |
|
40 | ```javascript
|
41 | {
|
42 | "filename": "view.js.pug",
|
43 | "options": {}, // passed options to the factory
|
44 | "source": "<x>y</x>",
|
45 | "parts": ["js", "pug"],
|
46 | "name": "view",
|
47 | "data": {}, // any data passed as front-matter
|
48 | "deps": [], // all imported-or-required sources
|
49 | "locals": {}, // values passed from the callback
|
50 | "isScript": false, // true for all exported modules
|
51 | }
|
52 | ```
|
53 |
|
54 | ### 1.2 - Rendering
|
55 |
|
56 | Example:
|
57 |
|
58 | ```javascript
|
59 | const tarima = require('tarima');
|
60 |
|
61 | const view = tarima.parse('view.rv.pug', 'x {{"y"}}');
|
62 |
|
63 | // direct
|
64 | view.render((err, result) => {
|
65 | console.log(err, result);
|
66 | });
|
67 | ```
|
68 |
|
69 | ### 1.3 - Bundling
|
70 |
|
71 | `view.bundle(locals, callback)` — Performs the transpilation on the given source, and turn it into a new module.
|
72 |
|
73 | Example:
|
74 |
|
75 | ```javascript
|
76 | // bundled
|
77 | view.bundle(locals, (err, result) => {
|
78 | console.log(err, result);
|
79 | });
|
80 | ```
|
81 |
|
82 | #### bundleOptions
|
83 |
|
84 | - `cwd` — Save all file paths relative to this directory
|
85 | - `cache` — Cache object being used by Rollup.js
|
86 | - `rollup` — Configuration object used by Rollup.js
|
87 |
|
88 | You can enable specific settings as:
|
89 |
|
90 | ```bash
|
91 | # from settings
|
92 | {
|
93 | "bundleOptions": {
|
94 | "buble": {},
|
95 | }
|
96 | }
|
97 | ```
|
98 |
|
99 | ### 1.4 - Front Matter
|
100 |
|
101 | All parsed files can use a front-matter block for local data.
|
102 |
|
103 | ```jade
|
104 | //-
|
105 | ---
|
106 | title: Untitled
|
107 | $render: other/layout.hbs
|
108 | extended: !include ../path/to.yml
|
109 | ---
|
110 |
|
111 | h1= title + extended.some.value
|
112 | ```
|
113 |
|
114 | Note you can merge additional files using the `!include` directive within any front-matter block.
|
115 |
|
116 | #### Special keys
|
117 |
|
118 | Tarima use some predefined keys in order to customize certain aspects of rendering, transpilation or bundling individually:
|
119 |
|
120 | - `$format` — This value is passed directly as `format` option for rollup, [available formats](https://github.com/rollup/rollup/wiki/JavaScript-API#format) are: `amd`, `js`, `es6`, `iife`, `umd`
|
121 | - `$bundle` — This value will be used as the exported symbol on bundles
|
122 | - `$render` — Render the current output as `yield` for the given source file
|
123 | - `$globals` — Global variables to bundle explicitly
|
124 | - `$external` — External modules to bundle explicitly
|
125 | - `$transpiler` — Set the transpiler for all ES6 sources
|
126 |
|
127 | ## 2.0 - Supported engines
|
128 |
|
129 | You can install the following dependencies for specific support:
|
130 |
|
131 | - `npm install coffeescript` → `.coffee` and `.litcoffee` (aka `.coffee.md`)
|
132 | - `npm install postcss` → `.post.css` sources (experimental)
|
133 | - `npm install pug` → `.pug` and `.jade` (legacy)
|
134 | - `npm install sass-node` → `.sass` and `.scss`
|
135 | - `npm install less` → `.less`
|
136 | - `npm install styl` → `.styl`
|
137 | - `npm install handlebars` → `.hbs`
|
138 | - `npm install kramed` → `.md`, `.mkd`
|
139 | - `npm install buble` → `.jsx` and `.es6.js`
|
140 | - `npm install traceur` → `.jsx` and `.es6.js`
|
141 | - `npm install sucrase` → `.jsx` and `.es6.js`
|
142 | - `npm install typescript` → `.ts` and `.tsx`
|
143 | - `npm install liquid-node` → `.sv` and `.liquid`
|
144 | - `npm install babel-core@^5` → `.jsx` and `.es6.js`
|
145 | - `npm install nodent` → to transpile `async/await` down to ES5
|
146 |
|
147 | Imported sources through Rollup.js will be processed anyway regardless they're supported or not.
|
148 |
|
149 | > Tarima doesn't ship any dependency for the supported engines, is your responsibility to install whatever you will need.
|
150 |
|
151 | ### 2.1 - ES6 support
|
152 |
|
153 | Tarima supports `.es6` through [Bublé](http://buble.surge.sh/) which is so damn fast and lot constrained than Babel, of course you can use Traceur too.
|
154 |
|
155 | Babel — `npm install babel-core@^6 babel-preset-es2015` to get the latest babel version with `es2015` as default preset:
|
156 |
|
157 | ```json
|
158 | {
|
159 | "bundleOptions": {
|
160 | "babel": {
|
161 | "presets": [["es2015", {}]]
|
162 | }
|
163 | }
|
164 | }
|
165 | ```
|
166 |
|
167 | ### 2.2 - Globals (and data)
|
168 |
|
169 | As part of the transpilation process you can put any value as global using the `globals` option:
|
170 |
|
171 | ```javascript
|
172 | tarima.parse('x.js', '/* global foo */console.log(foo);', {
|
173 | globals: {
|
174 | foo: 'bar'
|
175 | },
|
176 | }).render((err, result) => {
|
177 | console.log(result.source);
|
178 | });
|
179 | ```
|
180 |
|
181 | The previous code will output this:
|
182 |
|
183 | ```javascript
|
184 | var foo = "bar";
|
185 | console.log(foo);
|
186 | ```
|
187 |
|
188 | All given globals are injected in the sample place as the `/* global */` comment is declared.
|
189 |
|
190 | Also you can pass any value, even functions, because all values are normalized through the [tosource](https://github.com/marcello3d/node-tosource) module.
|
191 |
|
192 | Local `data` (either passed manually and front-matter) is always merged with globals, e.g.
|
193 |
|
194 | ```js
|
195 | /**
|
196 | ---
|
197 | foo: bar
|
198 | ---
|
199 | */
|
200 |
|
201 | /* global foo */
|
202 | console.log(foo);
|
203 | ```
|
204 |
|
205 | Resulting into:
|
206 |
|
207 | ```js
|
208 |
|
209 | var foo = "bar";
|
210 | console.log(foo);
|
211 | ```
|
212 |
|
213 | > Using this technique your code will always be valid on syntax terms. ;)
|
214 |
|
215 | The bundler will merge up all `importee.data` with the `importer.data` before processing.
|
216 |
|
217 | > Note globals are injected during the `post-filter`for all script sources, see below.
|
218 |
|
219 | #### Filters
|
220 |
|
221 | Tarima handle sources this way: `read -> pre-filter -> compile -> post-filter`.
|
222 |
|
223 | Passing a function as the `filter` option brings you the ability to modify the partial view during the `pre-filter` phase.
|
224 |
|
225 | #### Locals
|
226 |
|
227 | All supported templates can take locals, you can pass any values when calling `.render(locals, cb)` to draw them during the compile (or render) process.
|
228 |
|
229 | ## 3.0 - Command Line Interface
|
230 |
|
231 | 1. It can take any amount of files and produce different outputs based on supplied configuration, you can filter out some files, rename different subests, bundle them, etc.
|
232 |
|
233 | 2. Provides a simple hook system to catch-all non supported files, then are piped out to different handlers if they exists.
|
234 |
|
235 | 3. Otherwise, all non supported files are simply copied.
|
236 |
|
237 | It comes with basic dependency tracking, so any change will affect only its dependent sources.
|
238 |
|
239 | ### 3.1 - Basic usage
|
240 |
|
241 | The best way is adding tarima as dependency, global or locally, and then setup your `package.json` for using it:
|
242 |
|
243 | ```json
|
244 | {
|
245 | "scripts": {
|
246 | "dev": "tarima watch src",
|
247 | "build": "tarima src -fe production"
|
248 | }
|
249 | }
|
250 | ```
|
251 |
|
252 | Now calling `npm run dev` will start in watch-mode and `npm run build` will set `NODE_ENV=production` and force a complete rebuild of all sources.
|
253 |
|
254 | You can pass many source directories as arguments, but they can be difficult to maintain, so you can use the `tarima` object for settings:
|
255 |
|
256 | ```json
|
257 | {
|
258 | "scripts": {
|
259 | "dev": "tarima watch",
|
260 | "build": "tarima -fe production"
|
261 | },
|
262 | "tarima": {
|
263 | "from": [
|
264 | "src",
|
265 | "tests"
|
266 | ],
|
267 | "output": "lib"
|
268 | }
|
269 | }
|
270 | ```
|
271 |
|
272 | You can read sources `from` multiple directories.
|
273 |
|
274 | If no `output` is given `./build` will be used instead.
|
275 |
|
276 | ### 3.2 - Handling sources
|
277 |
|
278 | All files then are read or watch from given directories, any change will trigger a compilation process.
|
279 |
|
280 | This process will transpile the given source file if tarima supports it, if not it will be piped or copied as stated above.
|
281 |
|
282 | Basically you can write `./src/index.md` and obtain `./build/src/index.html` as result.
|
283 |
|
284 | > You'll notice that the source's filepath will be maintained as is, because you can specify multiple source directories and it will be difficult to resolve everything.
|
285 |
|
286 | You can use the `rename` option for cut-off directories from the destination filepath:
|
287 |
|
288 | ```
|
289 | {
|
290 | "tarima": {
|
291 | "rename": [
|
292 | "**:{basedir/1}/{fname}"
|
293 | ]
|
294 | }
|
295 | }
|
296 | ```
|
297 |
|
298 | This will match `./src/index.md` to `./build/index.html` directly.
|
299 |
|
300 | > The `{basedir/1}` expression will split the source's _dirname_ and remove the first directory from its left, e.g. `./dest/src/file.ext` becomes `./dest/file.ext` and such.
|
301 |
|
302 | Tarima will let you organize your source files as your pleasure, and them process them as you expect, to write them finally wherever you want.
|
303 |
|
304 | Not a complete building tool but damn useful for daily work.
|
305 |
|
306 | ### 3.3 - Notifications
|
307 |
|
308 | Tarima will use `node-notifier` to display some feedback about the process.
|
309 |
|
310 | You can customize some values of the notification popup:
|
311 |
|
312 | ```json
|
313 | {
|
314 | "tarima": {
|
315 | "notifications": {
|
316 | "title": "My app",
|
317 | "okIcon": "./success.png",
|
318 | "errIcon": "./failure.png"
|
319 | }
|
320 | }
|
321 | }
|
322 | ```
|
323 |
|
324 | ### 3.4 - Caching support
|
325 |
|
326 | Tarima is efficient by tracking dependencies using a json-file for caching, this way on each startup nothing will be compiled unless they are changes or dirty files.
|
327 |
|
328 | By default the cache file is `.tarima`, but you use a different file specifying the `cacheFile` option:
|
329 |
|
330 | ```json
|
331 | {
|
332 | "tarima": {
|
333 | "cacheFile": "tmp/cache.json"
|
334 | }
|
335 | }
|
336 | ```
|
337 |
|
338 | ### 3.5 - Bundle support
|
339 |
|
340 | By default all scripts are transpiled only, you must enable the `bundle` option for globally treat each entry-point as bundle.
|
341 |
|
342 | This option can be `true` to enable bundling on all files (filtered), a glob string, or an array of globs.
|
343 |
|
344 | > Files matching the globs will be treated as entry-points, see below.
|
345 |
|
346 | Or locally set the `$bundle` option as front-matter:
|
347 |
|
348 | ```javascript
|
349 | /**
|
350 | ---
|
351 | $bundle: true
|
352 | ---
|
353 | */
|
354 |
|
355 | import { getValue } from './other/script';
|
356 |
|
357 | export default function () {
|
358 | return getValue(...arguments);
|
359 | };
|
360 | ```
|
361 |
|
362 | > When using `$bundle` you don't need to declare it on each imported file, only within the entry-points you want to bundle.
|
363 |
|
364 | On javascript you can use the tilde prefix for loading sources from the `cwd`, e.g.
|
365 |
|
366 | ```js
|
367 | import pkg from '~/package.json';
|
368 |
|
369 | console.log(pkg.version);
|
370 | ```
|
371 |
|
372 | Even stylesheets are entry-points by nature:
|
373 |
|
374 | ```less
|
375 | @import 'colors.less';
|
376 |
|
377 | a { color: @link-text-color; }
|
378 | ```
|
379 |
|
380 | So you don't need anything else to bundle stylesheets. ;)
|
381 |
|
382 | ### 3.6 - Ignoring sources
|
383 |
|
384 | Ignoring sources will skip all matched files from watching, Tarima will never track them for any purpose.
|
385 |
|
386 | You can use the `ignoreFiles` to provide a glob-based file with patterns to be ignored.
|
387 |
|
388 | Example:
|
389 |
|
390 | ```json
|
391 | {
|
392 | "tarima": {
|
393 | "ignoreFiles": [".gitignore"]
|
394 | }
|
395 | }
|
396 | ```
|
397 |
|
398 | Any `.gitignore` compatible format is supported.
|
399 |
|
400 | ### 3.7 - Filtering sources
|
401 |
|
402 | Filtered sources are watched but not used for any transpilation process, they are ignored because they should be imported from any other entry-point file.
|
403 |
|
404 | A common pattern is ignoring everything which starts with underscore:
|
405 |
|
406 | ```json
|
407 | {
|
408 | "tarima": {
|
409 | "filter": [
|
410 | "!_*",
|
411 | "!_*/**",
|
412 | "!**/_*",
|
413 | "!**/_*/**"
|
414 | ]
|
415 | }
|
416 | }
|
417 | ```
|
418 |
|
419 | ### 3.8 - Rollup.js
|
420 |
|
421 | You can provide a configuration file for [rollup](https://github.com/rollup/rollup) using the `rollupFile` option:
|
422 |
|
423 | ```json
|
424 | {
|
425 | "tarima": {
|
426 | "rollupFile": "rollup.config.js"
|
427 | }
|
428 | }
|
429 | ```
|
430 |
|
431 | You can setup the specific behavior of bundling using `bundleOptions`:
|
432 |
|
433 | ```json
|
434 | {
|
435 | "tarima": {
|
436 | "bundleOptions": {
|
437 | "transpiler": "babel",
|
438 | "less": { "plugins": [] }
|
439 | }
|
440 | }
|
441 | }
|
442 | ```
|
443 |
|
444 | All given options are passed directly when calling the `view.bundle()` method.
|
445 |
|
446 | ### 3.9 - Locals
|
447 |
|
448 | You can pass a global `locals` object accesible for all parsed templates, this way you can reuse anything do you need:
|
449 |
|
450 | ```json
|
451 | {
|
452 | "tarima": {
|
453 | "locals": {
|
454 | "title": "My project"
|
455 | }
|
456 | }
|
457 | }
|
458 | ```
|
459 |
|
460 | Given locals are passed directly when calling any `render()` method on Tarima.
|
461 |
|
462 | ### 3.10 - Plugins
|
463 |
|
464 | Using the `plugins` option you can declare scripts or modules to be loaded and perform specific tasks, common plugins are:
|
465 |
|
466 | - `talavera` — support for sprites and lazy loading
|
467 | - `tarima-lr` — LiveReload integration (light-weight)
|
468 | - `tarima-browser-sync` — BrowserSync integration (heavy)
|
469 |
|
470 | Some plugins can take its configuration from `pluginOptions` or directly from the main configuration:
|
471 |
|
472 | ```json
|
473 | {
|
474 | "tarima": {
|
475 | "pluginOptions": {
|
476 | "buble": { "jsx": "h" }
|
477 | }
|
478 | }
|
479 | }
|
480 | ```
|
481 |
|
482 | All `plugins` are loaded automatically by Tarima on the startup.
|
483 |
|
484 | > `devPlugins` are loaded only if the watch-mode is enabled from CLI
|
485 |
|
486 | ### 3.11 - Settings
|
487 |
|
488 | - `cwd` — project's directory
|
489 | - `from` — source directories to process, not globs!
|
490 | - `output` — destination for generated files
|
491 | - `public` — public directory for serving assets
|
492 | - `cacheFile` — store processed details from files
|
493 | - `rename` — declare single rename operations, e.g. `M:N`
|
494 | - `filter` — set which files will be ignored from processing
|
495 | - `ignore` — skip sources, files, directories or globs from anything
|
496 | - `ignoreFiles` — extract `ignore` patterns from these files (see above)
|
497 | - `bundle` — enable bundling if it's `true`, or just files matching this
|
498 | - `bundleOptions` — enable settings for all processed sources (see above)
|
499 | - `plugins` — enable plugins for further processing, e.g. `talavera`
|
500 | - `devPlugins` — same as above, but only on watch-mode (e.g. `tarima-lr`)
|
501 | - `pluginOptions` — specific options for all enabled plugins
|
502 | - `flags` — given flags from CLI (or custom)
|
503 | - `locals` — data passed to all rendered sources
|
504 | - `reloader` — this script is invoked after any change
|
505 | - `watching` — additional files and directories to watch, globs will not work!
|
506 | - `notifications` — custom settings for `node-notifier`
|
507 |
|
508 | **Example of "tarima" settings**
|
509 |
|
510 | ```json
|
511 | {
|
512 | "cwd": ".",
|
513 | "from": [
|
514 | "lib/myapp/templates",
|
515 | "lib/myapp_web/assets"
|
516 | ],
|
517 | "watching": [
|
518 | "lib/myapp/application.js",
|
519 | "lib/myapp/chat",
|
520 | "lib/myapp/models",
|
521 | "lib/myapp/services",
|
522 | "lib/myapp_web/controllers",
|
523 | "lib/myapp_web/middlewares",
|
524 | "lib/myapp_web/middlewares.js",
|
525 | "lib/myapp_web/policies.js",
|
526 | "lib/myapp_web/routes.js",
|
527 | "config",
|
528 | ".env",
|
529 | "package.json"
|
530 | ],
|
531 | "filter": [
|
532 | "!_*",
|
533 | "!**/_*",
|
534 | "!**/_*/**"
|
535 | ],
|
536 | "bundle": [
|
537 | "**/templates/**",
|
538 | "**/javascripts/**"
|
539 | ],
|
540 | "rename": [
|
541 | "**/templates/**:{fullpath/2}",
|
542 | "**/assets/**:public/{fullpath/3}"
|
543 | ],
|
544 | "ignoreFiles": [
|
545 | ".gitignore"
|
546 | ],
|
547 | "devPlugins": [
|
548 | "tarima-lr"
|
549 | ],
|
550 | "plugins": [
|
551 | "talavera"
|
552 | ],
|
553 | "pluginOptions": {
|
554 | "talavera": {
|
555 | "dest": "public/images"
|
556 | },
|
557 | "tarima-lr": {
|
558 | "serve": "build/public",
|
559 | "timeout": 1000
|
560 | }
|
561 | },
|
562 | "bundleOptions": {
|
563 | "sourceMapFile": false,
|
564 | "bundleCache": false,
|
565 | "entryCache": false,
|
566 | "extensions": {
|
567 | "js": "es6",
|
568 | "css": "less"
|
569 | },
|
570 | "less": {
|
571 | "plugins": [
|
572 | "less-plugin-autoprefix"
|
573 | ]
|
574 | },
|
575 | "rollup": {
|
576 | "plugins": [
|
577 | "rollup-plugin-node-resolve",
|
578 | "rollup-plugin-commonjs"
|
579 | ],
|
580 | "rollup-plugin-node-resolve": {
|
581 | "module": true,
|
582 | "jsnext": true,
|
583 | "main": true,
|
584 | "browser": true
|
585 | }
|
586 | }
|
587 | }
|
588 | }
|
589 | ```
|