├── environments ├── atom-shell.md ├── node-webkit.md ├── nodejs.md ├── _template.md ├── browser.md └── browser-webworker.md ├── exports ├── _template.md ├── text.md ├── value.md ├── data.md ├── url.md ├── class.md ├── template-function.md ├── module.md ├── stylesheet.md ├── async-function.md └── rc-stylesheet.md ├── modifications ├── _template.md ├── module.md └── promise.md ├── contents └── _template.md └── README.md /environments/atom-shell.md: -------------------------------------------------------------------------------- 1 | # `atom-shell` 2 | 3 | https://github.com/atom/atom-shell 4 | 5 | ## features 6 | 7 | -------------------------------------------------------------------------------- /environments/node-webkit.md: -------------------------------------------------------------------------------- 1 | # `node-webkit` 2 | 3 | https://github.com/rogerwang/node-webkit 4 | 5 | ## features 6 | 7 | -------------------------------------------------------------------------------- /environments/nodejs.md: -------------------------------------------------------------------------------- 1 | # `nodejs` 2 | 3 | node.js 4 | 5 | ## features 6 | 7 | ### `+es5` 8 | 9 | Has full ECMAScript 5 support. 10 | -------------------------------------------------------------------------------- /environments/_template.md: -------------------------------------------------------------------------------- 1 | # `{name}` 2 | 3 | {description} 4 | 5 | ## features 6 | 7 | ### `+{featureName}` 8 | 9 | {featureDescription} 10 | -------------------------------------------------------------------------------- /environments/browser.md: -------------------------------------------------------------------------------- 1 | # `browser` 2 | 3 | A web browser. 4 | 5 | ## features 6 | 7 | ### `+es5` 8 | 9 | Has full ECMAScript 5 support. 10 | -------------------------------------------------------------------------------- /environments/browser-webworker.md: -------------------------------------------------------------------------------- 1 | # `browser-webworker` 2 | 3 | A WebWorker running inside a web browser. 4 | 5 | ## features 6 | 7 | All features of [`browser`](browser.md). 8 | -------------------------------------------------------------------------------- /exports/_template.md: -------------------------------------------------------------------------------- 1 | # `{name}` 2 | 3 | {description} 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/text.md: -------------------------------------------------------------------------------- 1 | # `text` 2 | 3 | A string is exported. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /modifications/_template.md: -------------------------------------------------------------------------------- 1 | # `{name}` 2 | 3 | {description} 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/value.md: -------------------------------------------------------------------------------- 1 | # `value` 2 | 3 | Any value is exported. This can be anything. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/data.md: -------------------------------------------------------------------------------- 1 | # `data` 2 | 3 | Pure data, without code. No functions, no modified getter/setter. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/url.md: -------------------------------------------------------------------------------- 1 | # `url` 2 | 3 | Exports an URL. It can be any URL, including DataUrls, absolute URLs and relative paths. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/class.md: -------------------------------------------------------------------------------- 1 | # `class` 2 | 3 | A constructor function is exported. It's only allowed to use it with the `new` keyword. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/template-function.md: -------------------------------------------------------------------------------- 1 | # `template-function` 2 | 3 | A function is exported that returns a string when called. It may expect arguments. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /exports/module.md: -------------------------------------------------------------------------------- 1 | # `module` 2 | 3 | A ES6-like module is exported. This means it can have multiple named exports and can have one default export. 4 | 5 | ## example 6 | 7 | ``` 8 | {example} 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /modifications/module.md: -------------------------------------------------------------------------------- 1 | # `module` 2 | 3 | Coverts a value exporting module in a ES6-like module by moving the exported value into the default export. 4 | 5 | ## example 6 | 7 | `abc` is of type `module/text/markdown`. 8 | 9 | ``` 10 | import theText from "abc"; 11 | ``` 12 | 13 | ## support 14 | 15 | | {implementation} | 16 | |------------------| 17 | | {version} | 18 | 19 | ## features 20 | 21 | ### `+{featureName}` 22 | 23 | {featureDescription} 24 | 25 | | {implementation} | 26 | |------------------| 27 | | {version} | 28 | -------------------------------------------------------------------------------- /exports/stylesheet.md: -------------------------------------------------------------------------------- 1 | # `stylesheet` 2 | 3 | A stylesheet is exported. By importing a module of this kind the css rules are applied to the current document. From outside this acts like an empty ES6-like module. 4 | 5 | ## example 6 | 7 | ``` javascript 8 | import "abc"; 9 | ``` 10 | 11 | ## support 12 | 13 | | {implementation} | 14 | |------------------| 15 | | {version} | 16 | 17 | ## features 18 | 19 | ### `+{featureName}` 20 | 21 | {featureDescription} 22 | 23 | | {implementation} | 24 | |------------------| 25 | | {version} | 26 | -------------------------------------------------------------------------------- /contents/_template.md: -------------------------------------------------------------------------------- 1 | # `{name}` 2 | 3 | {description} 4 | 5 | ## `{export}/{name}` 6 | 7 | {description} 8 | 9 | ### example 10 | 11 | ``` 12 | {example} 13 | ``` 14 | 15 | ## support 16 | 17 | | {implementation} | 18 | |------------------| 19 | | {version} | 20 | 21 | ## features 22 | 23 | ### `+{featureName}` 24 | 25 | {featureDescription} 26 | 27 | | {implementation} | 28 | |------------------| 29 | | {version} | 30 | 31 | ## exports 32 | 33 | ### `{exportName}/{name}` 34 | 35 | {description} 36 | 37 | | {implementation} | 38 | |------------------| 39 | | {version} | 40 | -------------------------------------------------------------------------------- /modifications/promise.md: -------------------------------------------------------------------------------- 1 | # `promise` 2 | 3 | Exports an ES6-like promise, which eventually resolve (or has already resolved) to the exports. 4 | 5 | The module system can decide whether to load the module on demand or not. It'll prefer on-demand loading. 6 | 7 | ## example 8 | 9 | ``` 10 | {example} 11 | ``` 12 | 13 | ## support 14 | 15 | | {implementation} | 16 | |------------------| 17 | | {version} | 18 | 19 | ## features 20 | 21 | ### `+eager` 22 | 23 | On demand loading is not allowed. This fail to compile if the module system only supports on-demand loading. 24 | 25 | | {implementation} | 26 | |------------------| 27 | | {version} | 28 | 29 | ### `+lazy` 30 | 31 | On demand loading is enforced. This fail to compile if the module system doesn't support on-demand loading. 32 | 33 | | {implementation} | 34 | |------------------| 35 | | {version} | 36 | -------------------------------------------------------------------------------- /exports/async-function.md: -------------------------------------------------------------------------------- 1 | # `async-function` 2 | 3 | An asynchronous function is exported. The last argument passed to the exported function is always a callback function that is allowed to be called with delay. 4 | 5 | The module system can decide whether to load the module on demand or not. It'll prefer on-demand loading. 6 | 7 | ## example 8 | 9 | ``` 10 | {example} 11 | ``` 12 | 13 | ## support 14 | 15 | | {implementation} | 16 | |------------------| 17 | | {version} | 18 | 19 | ## features 20 | 21 | ### `+eager` 22 | 23 | On demand loading is not allowed. This fail to compile if the module system only supports on-demand loading. 24 | 25 | | {implementation} | 26 | |------------------| 27 | | {version} | 28 | 29 | ### `+lazy` 30 | 31 | On demand loading is enforced. This fail to compile if the module system doesn't support on-demand loading. 32 | 33 | | {implementation} | 34 | |------------------| 35 | | {version} | 36 | -------------------------------------------------------------------------------- /exports/rc-stylesheet.md: -------------------------------------------------------------------------------- 1 | # `rc-stylesheet` 2 | 3 | A reference-counted stylesheet is exported. It exports two symbols: `ref` and `unref`. Both are functions. 4 | 5 | `ref()` Increases the reference counter by one. If the reference counter is now one the css rules are added to the current document. 6 | 7 | `unref()` Decreases the reference counter by one. If the reference counter is now zero the css rules are removed from the current document. 8 | 9 | ## example 10 | 11 | ``` javascript 12 | import { ref, unref } from "abc"; 13 | 14 | // No css rules applied 15 | 16 | ref(); 17 | 18 | // css rules are now applied 19 | 20 | unref(); 21 | 22 | // css rules are no longer applied 23 | ``` 24 | 25 | ## support 26 | 27 | | {implementation} | 28 | |------------------| 29 | | {version} | 30 | 31 | ## features 32 | 33 | ### `+{featureName}` 34 | 35 | {featureDescription} 36 | 37 | | {implementation} | 38 | |------------------| 39 | | {version} | 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # concord 2 | 3 | A spec for modules. concord modules. 4 | 5 | ## Goals 6 | 7 | * Reuseable modules that can be used independent of the build system. 8 | * Allow to use different module types and describe dependencies between them. i. e. 9 | * code (javascript, coffeescript) 10 | * data (json, text, yaml) 11 | * stylesheet (css, less, stylus) 12 | * image (png, jpg), shader (glsl) 13 | * font (ttf, woff) 14 | * template (html, jade) 15 | * WebWorker (javascript, coffeescript) 16 | * on-demand loaded 17 | * Dependencies for module types other than code should be allowed too. i. e. 18 | * stylesheets depend on images and fonts 19 | * templates depend on images 20 | * Allow modules to be used in different environments. i. e. 21 | * browser (es3, es5, es6) 22 | * WebWorker 23 | * server (node.js) 24 | * browser plugin 25 | * standalone GUI app (node-webkit, atom-shell) 26 | * Allow the application using the concords to specify/override how different module types are handled. i. e. 27 | * images as DataUrl or as file 28 | * stylesheets inlined or as separate file 29 | * code/template/images minimized or with SourceMap 30 | * svg as code or converted into png 31 | * load module on demand or not 32 | * polyfill es5/es6 features or expect modern browser 33 | * Don't require the module author to run any build system before publishing the module, but allow them to run it for generating assets usable without build system. 34 | * Don't expect from the build system to handle all module types. 35 | * Allow the module author to conditionally use modules depending on module type and feature support of the build system. 36 | * Allow to specify custom module types. 37 | * Don't make the build unnecessary complex to allow fast builds. 38 | * A concord should be useable after installing. The user (app author or other module authors) shouldn't need to configure special preprocessing. 39 | * Easy to configure for app and module authors 40 | * Easy to add concord support for existing modules 41 | * concord shouldn't be a package manager. Instead it should reuse an existing package manager (i. e. npm). 42 | 43 | ## Existing stuff 44 | 45 | 46 | 47 | ### [browserify](http://browserify.org/) style modules 48 | 49 | browserifys approach is to use only node.js-compatible modules plus code and transform this code for the used environment (here browser). 50 | 51 | Example: loading HTML file 52 | 53 | ``` javascript 54 | // package.json 55 | "browserify": { "transforms": ["brfs"] } 56 | ``` 57 | 58 | ``` javascript 59 | var fs = require("fs"); 60 | var content = fs.readFileSync(__dirname + "/file.html", "utf-8"); 61 | ``` 62 | 63 | A transform ([brfs](https://github.com/substack/brfs)) is used and the code is transformed to something like this: 64 | 65 | ``` javascript 66 | var content = ""; 67 | ``` 68 | 69 | #### positive 70 | 71 | * perfect node.js compatibility 72 | * already many modules in npm 73 | * nothing need to be configured on application level to use modules 74 | 75 | #### negative 76 | 77 | * the exact process of preprocessing needs to be specified in the code 78 | (i. e. `addStylesheet(compileLess(fs.readFileSync(__dirname + "/style.less", "utf-8")))`) 79 | * the transform needs to load and parse each code file to find dependencies. 80 | Multiple transforms means the code is parsed multiple times. Performance! 81 | * You need to repeat yourself when using many files of the same module type 82 | * transforms are too simple to handle complex tasks, i.e. depending on more files 83 | 84 | #### open questions 85 | 86 | * How to handle module types that are not supported in a server environment? (i. e. stylesheets, WebWorker) 87 | * How to handle dependencies in module types other than javascript? (i. e. images in HTML) 88 | * How to alternate the behaviour from the application? (i. e. emit images in separate files instead of inlined) 89 | 90 | 91 | 92 | ### [component](https://github.com/componentjs/component) 93 | 94 | A per-module configuration file (`component.json`) defines dependencies. A predefined set of module types is supported (code (javascript), data (json), stylesheets (css), templates (raw text), images, runtime files). It's expected from the module author to compile all other module types into these module types. 95 | 96 | ``` javascript 97 | // component.json 98 | templates: ["file.html"] 99 | ``` 100 | 101 | ``` javascript 102 | var content = require("./file.html"); 103 | ``` 104 | 105 | The build system adds `file.html` as string module to the bundle: 106 | 107 | ``` javascript 108 | var content = require("./file.html"); 109 | // --- 110 | ""; 111 | ``` 112 | 113 | #### positive 114 | 115 | * modules are reusable 116 | * It's easy to implement a new build system, because only a predefined set of module types is supported 117 | * You can override the default behaviour of a module type in the bundler (i. e. inline images with DataUrls) 118 | 119 | #### negative 120 | 121 | * only browser environment supported 122 | * all modules types must be supported by the module system. Adding new module types is difficult as all build systems must support the new module type. 123 | This means it's difficult to extend. 124 | * module authors must compile the modules when using other modules types than the supported ones. 125 | * it's a package manager and has its own registry 126 | * you cannot use the module in node.js as it's installed in a separate folder, but you can publish the same module to both registries 127 | 128 | 129 | 130 | ### [webpack 1.x](http://webpack.github.io/) 131 | 132 | In a pre-app configuration file (webpack.config.js) you configure loaders for files. Modules that use different module types need to tell the app author to add the right loaders to the configuration file. 133 | 134 | ``` javascript 135 | // webpack.config.js 136 | { test: /\.html$/, loader: "html-loader" }, 137 | { test: /\.png$/, loader: "file-loader" } 138 | ``` 139 | 140 | ``` javascript 141 | var content = require("./file.html"); 142 | ``` 143 | 144 | The build system preprocesses the required file with the specified loader and this will result in a generated module. The generated module can have dependencies. 145 | 146 | ``` javascript 147 | var content = __webpack_require__(2); 148 | // --- 149 | module.exports = ""; 150 | // --- 151 | module.exports = "/path/6f87a6b7e188b838e842ab23.png" 152 | ``` 153 | 154 | #### positive 155 | 156 | * module type behaviour is specified on application level, i.e. it's easy to choose between image as DataUrl or file 157 | * multiple loaders can be chained to create multiple levels of transformation 158 | 159 | #### negative 160 | 161 | * Using an module with modules types different than pure javascript requires configuration on application level 162 | * webpack specific loader syntax. 163 | 164 | 165 | 166 | ## concord 167 | 168 | ### How it's different 169 | 170 | Existing stuff defines how modules are processed on package-level. With concord the package defines only the types of modules and doesn't define how they are processed. How the different types of modules are processed is defined on application level. Useful defaults for each module type ensure that packages are usable without configuration. 171 | 172 | The indirect mapping from *file* to *module type* to *processing logic* ensures that packages are independent of build system and *module processors*. It also makes sure that the application has the ultimate control over module processing. 173 | 174 | ### definitions 175 | 176 | **type plus features**: This is often used for specifying types. It combines a *basetype* with a list of additional *features*: `basetype+feature1+feature2+feature3`. An addition of an feature must behave equally to the thing without this feature if the feature isn't used. So if `a+b+c` is required `a+b+c+d` could be used instead and will behave similar to `a+b+c` or `a+b+c+e`. `*` as *basetype* will match every *basetype*. 177 | 178 | **environment**: The target of the generated thing. There can be multiple environments. It's defined with a *type plus features*. Examples: `web+es5`, `node+es5+es6` 179 | 180 | 181 | ### package configuration 182 | 183 | ``` javascript 184 | { 185 | "concord": { 186 | "main": "./main", 187 | "[server] main": "./server-main", 188 | "extensions": ["", ".js", ".coffee", ".less"], 189 | "types": { 190 | "./lib/*.js": "object/javascript+commonjs+es5", 191 | "./**/*.less": "stylesheet/less", 192 | "[server] ./styles/*.less": "nothing/irrelevant", 193 | "*.coffee": "object/coffeescript", 194 | "*.{png|jpg|gif}": "url/image", 195 | "./package.json": "data+immutable/json", 196 | "socket.io": "promise+lazy/*", 197 | "socket.io/client": "object/javascript+amd" 198 | }, 199 | "modules": { 200 | "config": "./default-config", 201 | "[web] config": "./web-config", 202 | "./file": "./concord-file", 203 | "./ignored": false 204 | } 205 | } 206 | } 207 | ``` 208 | 209 | #### file 210 | 211 | The concord configuration can be in the package manager configuration file. 212 | 213 | Examples: 214 | 215 | * `npm`: `package.json` 216 | * `bower`: `bower.json` 217 | 218 | Which package manager is used depends on the build system. A build system may support multiple package managers. 219 | 220 | #### conditional keys 221 | 222 | `main`, `extensions` and every key in the `types` object can be conditional. The author can specify this by prefixing a expression in brackets `[...]`. 223 | 224 | Logical operations are possible via this syntax: and `[...][...]`, or `[...|...]`, not `[!...]`. 225 | 226 | Spacing is optionally possible and ignored by the build system. Examples: `[ ... ] key`, `[ ... | ... ] [ ... ] key`. 227 | 228 | Depending on the style of the expression, it's matched against the environment or the supported module types. 229 | 230 | The only supported order of different versions of the same key is this one: the unconditional version must go first (if it exists), immediate followed by the conditional versions. Only last matched version is the used value of the key. 231 | 232 | Conditional configuration can be applied in a preprocessing step to the configuration. 233 | 234 | Examples: 235 | 236 | * matched against the environment 237 | * `[server]` 238 | * `[web+es6]` 239 | * `[*+es6+my-custom-flag]` 240 | * matched against the supported module types (containing a `/`) 241 | * `[url/image]` 242 | * `[data+immutable/json]` 243 | * `[promise+lazy/*]` 244 | 245 | Example configuration: 246 | 247 | ``` javascript 248 | "types": { 249 | "./large-file": "promise/*", 250 | "[web] [promise+lazy/*] ./large-file": "promise+lazy/*", 251 | "[server] ./large-file": "promise+eager/*", 252 | } 253 | ``` 254 | 255 | By default `promise/*` is used for `large-file`, but if lazy-loading (`promise+lazy/*`) is supported this is used for `web` environment. For a `server` environment the lazy-loading is disabled (`promise+eager/*`). If building for `web` and `server` environment lazy-loading is disabled, because it's later specified in the configuration. 256 | 257 | #### `concord` 258 | 259 | Every `concord` option in scoped with this key. This ensures that concord doesn't conflict with other configuration. 260 | 261 | The only allowed keys in this object are: `main`, `extensions`, `types` and `modules`. When the build system find other keys it should fail assuming there is a newer concord version, which is not supported by this build system. 262 | 263 | #### `main` 264 | 265 | When the request resolves to the main directory of this package (the directory of the configuration file), the content of the `main` field is resolved relative to the package directory (Meaning `./` is required for relative paths). 266 | 267 | The `main` field from the concord configuration defaults to package manager configuration module entry point. i. e. `main` in `package.json` or `"./index"`. 268 | 269 | #### `extensions` 270 | 271 | An array of strings that are appended to requests that resolve inside the package. This is also used when resolving from another package into this package i. e. `module/file`. 272 | 273 | This also defaults to the package manager default. 274 | 275 | #### `modules` 276 | 277 | This key is similar to the [browser field proposed by defunctzombie](https://gist.github.com/defunctzombie/4339901). 278 | 279 | This object configuration replacements and aliases used for requests that resolve inside the package. When the *key* matches the request the *value* is used instead. 280 | 281 | Relative *keys* (starting with `./`): The *key* is relative to the package directory and every request which matches that file is replaced. This means a key `./dir/file` can be matched by `module/dir/file`, `module/dir/file.js`, `./file` (when issued from `module/dir/other-file.js`). 282 | 283 | Module *keys* (starting with a module name): It's matched when the exact same string is used from a file **inside** the package. Dependencies of the package are not affected. 284 | 285 | string *value*: This request is resolved instead, it's resolved relative to the package directory. 286 | 287 | `false` *value*: A empty module is used instead. It exports an empty object. It's assumes that this object isn't used. 288 | 289 | Globbing can be used for the keys except the module part. `*`: matches anything but `/`, `**` matches anything, `{a,b,c}` matches `a`, `b` or `c`. 290 | 291 | There is a special case when the key doesn't start with `./` but with a string containing `*` before the first `/`. This cannot be a module *key* because the module *key* is not allowed to contain `*` (no globbing for the module part). So in this case it is threaded as relative *key*, but it don't need to match the complete path. Examples: `*.js` matches every javascript file, `view-*/*` matches every file in a directory starting with `view-`, `case/*.js` matches `./test/case/xyz.js` but not `./testcase/xyz.js`. 292 | 293 | Example: 294 | 295 | * relative 296 | * `./file.html` matches the file `file.html` in the package directory 297 | * `./dir/abc.js` matches the file `abc.js` in the directory `dir` in the package directory 298 | * `./ 299 | 300 | #### `types` 301 | 302 | The *keys* of the object are threaded equally to the *keys* in `modules` above. 303 | 304 | The *value* specifies the module type. The entries are processed in order from top to bottom. When a entry is matched the module type is set to the *value*. `*` in the *value* is replaced with the previous *value*. 305 | 306 | For a module *key* the previous value is obtained from the modules' concord configuration. 307 | 308 | The value defaults to `object/javascript` for `*.js` and to `object/json` for `*.json`. 309 | 310 | Example: 311 | 312 | ``` javascript 313 | "types": { 314 | "*.less": "stylesheet/less", 315 | "./styles/*": "promise/*", 316 | "module": "promise/*" 317 | } 318 | ``` 319 | 320 | `a.less` has the module type `stylesheet/less`. `styles/b.less` has the module type `promise/stylesheet/less`. `c.css` failed because it has no module type. `styles/c.css` fails because while applying `"promise/*"` no previous module type is defined. `module` has i. e. the module type `promise/object/javascript`. 321 | 322 | ### module type 323 | 324 | ``` text 325 | module-type 326 | modifications "/" export-type "/" content-type 327 | export-type "/" content-type 328 | 329 | modifications 330 | modifications "/" modification-type 331 | modification-type 332 | 333 | export-type 334 | type-with-features 335 | 336 | content-type 337 | type-with-features 338 | 339 | modification-type 340 | type-with-features 341 | 342 | type-with-features 343 | type ( "+" feature )* 344 | ``` 345 | 346 | The **content type** explains the content of the file. 347 | 348 | The **export type** explains what is expected to be exported from the module. This also summarizes side effects from loading this module. 349 | 350 | The **modification type** explains how the original export is modified. 351 | 352 | #### example content types 353 | 354 | * `css` `less` `stylus`: a stylesheet written in css/less/stylus 355 | * `javascript`: a module written in javascript 356 | * `+commonjs`: CommonJs is supported (`this` is `exports`) 357 | * `+amd`: AMD is supported 358 | * `+global`: `this` is `window` 359 | * `+es5` `+es6` 360 | * `json`: a stringified json object 361 | * `image`: an image 362 | * `+lossless` 363 | * `+lossy` 364 | * `+descriptive` 365 | * `+pixels` 366 | * `font`: a font 367 | * `irrelevant`: The content is not relevant 368 | 369 | #### example export types 370 | 371 | * `object`: any javascript object (or primive value) is exported 372 | * `data`: data (no code: no functions or modified getter/setter) 373 | * `+immutable`: data will never be changed (allows optimizations like inlining) 374 | * `template-function`: a function returning a string is exported 375 | * `class`: a javascript constructor is exported 376 | * `stylesheet`: css rules are applied to the document 377 | * `rc-stylesheet`: stylesheet wrapped in a reference-counted container. 378 | * `text`: exported string 379 | * `url`: an URL 380 | 381 | #### example modification types 382 | 383 | * `promise`: The export is wrapped in a promise (on demand loading is preferred) 384 | * `+eager`: thing is not loaded on demand 385 | * `+lazy`: thing is loaded on demand 386 | 387 | ### application configuration 388 | 389 | On application-level there need to be some mechanism to bind module types to preprocessing instructions. This is handled by the build system. 390 | 391 | I. e. with webpack 2.x the application author can match module types to loaders: 392 | 393 | ``` javascript 394 | { 395 | "stylesheet/less": "style-loader!css-loader!less-loader", 396 | "*/javascript+commonjs+amd": "", 397 | "*/javascript+global": "imports-loader?this=>window", 398 | "url/image+lossless+lossy+descriptive+pixels": "file-loader?name=img/[hash:10].[ext]", 399 | "url/font": "file-loader?name=font/[hash:10].[ext]", 400 | "promise+lazy/*": "promise-loader", 401 | } 402 | ``` 403 | 404 | ### application configuration database 405 | 406 | There is a database for each build system, that provides defaults for most module types. So by default there is no application-level configuration required, but you can override it or provide additional module types. 407 | 408 | The database delegates installing of required dependencies to the package manager. So the user don't need to care about dependencies the build system requires for preprocessing stuff. It needs to be allowed to install and use multiple versions of the same dependency. 409 | 410 | i. e. webpack 2.x 411 | 412 | ``` javascript 413 | { 414 | "stylesheet/less": { 415 | value: "style-loader!css-loader!less-loader", 416 | dependencies: { 417 | "style-loader": "~0.8.2", 418 | "css-loader": "~0.8.1", 419 | "less-loader": "~0.6.0", 420 | } 421 | } 422 | // ... 423 | } 424 | ``` 425 | 426 | # webpack 2.x 427 | 428 | webpack 2.x will support concord. Loaders will get the internal preprocessing format for concord with webpack. 429 | --------------------------------------------------------------------------------