This commit is contained in:
chrosey
2017-09-13 07:52:34 +02:00
parent a1f16c37f4
commit 2340b0226b
24621 changed files with 2912161 additions and 149 deletions
+5
View File
@@ -0,0 +1,5 @@
root = true
[*.js]
indent_style=tab
trim_trailing_whitespace=true
+24
View File
@@ -0,0 +1,24 @@
{
"env": {
"node": true
},
"rules": {
"strict": 0,
"camelcase": 0,
"curly": 0,
"indent": [2, "tab", { "SwitchCase": 1 }],
"eol-last": 1,
"no-shadow": 0,
"no-redeclare": 2,
"no-extra-bind": 1,
"no-empty": 0,
"no-process-exit": 1,
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"no-unused-vars": 0,
"consistent-return": 0,
"no-inner-declarations": 1,
"no-loop-func": 1,
"space-before-function-paren": [2, "never"]
}
}
+41
View File
@@ -0,0 +1,41 @@
## **BEFORE YOU SUBMIT** please read the following:
If you have a support request or question please
submit them to [StackOverflow](http://stackoverflow.com/questions/tagged/webpack) using the tag `[webpack]` or the [webpack Gitter](https://gitter.im/webpack/webpack). Future support requests will be closed.
(remove this from issue)
**I'm submitting a bug report**
**I'm submitting a feature request**
**I'm submitting a support request** => Please do not submit support request here, see note at the top of this template.
(remove inappropriate sentences)
**Webpack version:**
1.10.x / 2.x
**HTML-Loader version:**
0.3.x / 0.4.x
**Please tell us about your environment:**
OSX 10.x / Linux / Windows 10
**Current behavior:**
**Expected/desired behavior:**
* **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem along with a gist/jsbin of your webpack configuration.**
* **What is the expected behavior?**
* **What is the motivation / use case for changing the behavior?**
* **Browser:** [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
* **Language:** [all | TypeScript X.X | ES6/7 | ES5 | Dart | ...]
+34
View File
@@ -0,0 +1,34 @@
**Please check if the PR fulfills these requirements**
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
**What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, local variables)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] CI related changes
- [ ] Other... Please describe:
**What is the current behavior?** (You can also link to an open issue here)
**What is the new behavior?**
**Does this PR introduce a breaking change?**
- [ ] Yes
- [ ] No
If this PR contains a breaking change, please describe the following...
* Impact:
* Migration path for existing applications:
* Github Issue(s) this is regarding:
**Other information**:
+26
View File
@@ -0,0 +1,26 @@
{
"js": {
"allowed_file_extensions": ["js", "json", "jshintrc", "jsbeautifyrc"],
"brace_style": "collapse",
"break_chained_methods": false,
"e4x": true,
"eval_code": false,
"end_with_newline": true,
"indent_char": "\t",
"indent_level": 0,
"indent_size": 1,
"indent_with_tabs": true,
"jslint_happy": false,
"jslint_happy_align_switch_case": true,
"space_after_anon_function": false,
"keep_array_indentation": false,
"keep_function_indentation": false,
"max_preserve_newlines": 2,
"preserve_newlines": true,
"space_before_conditional": false,
"space_in_paren": false,
"unescape_strings": false,
"wrap_line_length": 0
}
}
+20
View File
@@ -0,0 +1,20 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
node_modules
coverage
examples
test
assets
.idea
+14
View File
@@ -0,0 +1,14 @@
sudo: false
language: node_js
os:
- linux
node_js:
- node
- "6"
- "4"
script: npm run travis
after_success:
- cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js
- rm -rf ./coverage
+42
View File
@@ -0,0 +1,42 @@
# Contributing
From opening a bug report to creating a pull request: every contribution is
appreciated and welcome. If you're planning to implement a new feature or change
the api please create an issue first. This way we can ensure that your precious
work is not in vain.
## Issues
Most of the time, if webpack is not working correctly for you it is a simple configuration issue.
If you are having difficulty, please search the [StackOverflow with the webpack tag](http://stackoverflow.com/tags/webpack) for questions related
to the `html-loader`. If you can find an answer to your issue, please post a question in [StackOverflow](http://stackoverflow.com/tags/webpack) or
the [webpack Gitter](https://gitter.im/webpack/webpack) and include both your webpack & html-loader versions.
**If you have discovered a bug or have a feature suggestion, feel free to create an issue on Github.**
## Setup
```bash
git clone https://github.com/webpack/html-loader.git
cd html-loader
npm install
```
To run the entire test suite use:
```bash
npm test
```
## Submitting Changes
After getting some feedback, push to your fork and submit a pull request. We
may suggest some changes or improvements or alternatives, but for small changes
your pull request should be accepted quickly.
Some things that will increase the chance that your pull request is accepted:
* Write tests
* Follow the existing Webpack coding style defined in the eslint jsbeutify and editor config rules.
* Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+305
View File
@@ -0,0 +1,305 @@
[![npm][npm]][npm-url]
[![deps][deps]][deps-url]
[![test][test]][test-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
<div align="center">
<img width="200" height="200"
src="https://worldvectorlogo.com/logos/html5.svg">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200" vspace="" hspace="25"
src="https://worldvectorlogo.com/logos/webpack.svg">
</a>
<h1>HTML Loader</h1>
<p>Exports HTML as string. HTML is minimized when the compiler demands.<p>
</div>
<h2 align="center">Install</h2>
```bash
npm i -D html-loader
```
<h2 align="center">Usage</h2>
By default every local `<img src="image.png">` is required (`require('./image.png')`). You may need to specify loaders for images in your configuration (recommended `file-loader` or `url-loader`).
You can specify which tag-attribute combination should be processed by this loader via the query parameter `attrs`. Pass an array or a space-separated list of `<tag>:<attribute>` combinations. (Default: `attrs=img:src`)
To completely disable tag-attribute processing (for instance, if you're handling image loading on the client side) you can pass in `attrs=false`.
<h2 align="center">Examples</h2>
With this configuration:
```js
{
module: {
rules: [
{ test: /\.jpg$/, use: [ "file-loader" ] },
{ test: /\.png$/, use: [ "url-loader?mimetype=image/png" ] }
]
},
output: {
publicPath: "http://cdn.example.com/[hash]/"
}
}
```
``` html
<!-- file.html -->
<img src="image.png" data-src="image2x.png" >
```
```js
require("html-loader!./file.html");
// => '<img src="http://cdn.example.com/49eba9f/a992ca.png"
// data-src="image2x.png">'
```
```js
require("html-loader?attrs=img:data-src!./file.html");
// => '<img src="image.png" data-src="data:image/png;base64,..." >'
```
```js
require("html-loader?attrs=img:src img:data-src!./file.html");
require("html-loader?attrs[]=img:src&attrs[]=img:data-src!./file.html");
// => '<img src="http://cdn.example.com/49eba9f/a992ca.png"
// data-src="data:image/png;base64,..." >'
```
```js
require("html-loader?-attrs!./file.html");
// => '<img src="image.jpg" data-src="image2x.png" >'
```
minimized by running `webpack --optimize-minimize`
```html
'<img src=http://cdn.example.com/49eba9f/a9f92ca.jpg
data-src=data:image/png;base64,...>'
```
or specify the `minimize` property in the rule's options in your `webpack.conf.js`
```js
module: {
rules: [{
test: /\.html$/,
use: [ {
loader: 'html-loader',
options: {
minimize: true
}
}],
}]
}
```
### 'Root-relative' URLs
For urls that start with a `/`, the default behavior is to not translate them.
If a `root` query parameter is set, however, it will be prepended to the url
and then translated.
With the same configuration as above:
``` html
<!-- file.html -->
<img src="/image.jpg">
```
```js
require("html-loader!./file.html");
// => '<img src="/image.jpg">'
```
```js
require("html-loader?root=.!./file.html");
// => '<img src="http://cdn.example.com/49eba9f/a992ca.jpg">'
```
### Interpolation
You can use `interpolate` flag to enable interpolation syntax for ES6 template strings, like so:
```js
require("html-loader?interpolate!./file.html");
```
```html
<img src="${require(`./images/gallery.png`)}">
<div>${require('./components/gallery.html')}</div>
```
And if you only want to use `require` in template and any other `${}` are not to be translated, you can set `interpolate` flag to `require`, like so:
```js
require("html-loader?interpolate=require!./file.ftl");
```
```html
<#list list as list>
<a href="${list.href!}" />${list.name}</a>
</#list>
<img src="${require(`./images/gallery.png`)}">
<div>${require('./components/gallery.html')}</div>
```
### Export formats
There are different export formats available:
+ ```module.exports``` (default, cjs format). "Hello world" becomes ```module.exports = "Hello world";```
+ ```exports.default``` (when ```exportAsDefault``` param is set, es6to5 format). "Hello world" becomes ```exports.default = "Hello world";```
+ ```export default``` (when ```exportAsEs6Default``` param is set, es6 format). "Hello world" becomes ```export default "Hello world";```
### Advanced options
If you need to pass [more advanced options](https://github.com/webpack/html-loader/pull/46), especially those which cannot be stringified, you can also define an `htmlLoader`-property on your `webpack.config.js`:
```js
var path = require('path')
module.exports = {
...
module: {
rules: [
{
test: /\.html$/,
use: [ "html-loader" ]
}
]
},
htmlLoader: {
ignoreCustomFragments: [/\{\{.*?}}/],
root: path.resolve(__dirname, 'assets'),
attrs: ['img:src', 'link:href']
}
};
```
If you need to define two different loader configs, you can also change the config's property name via `html-loader?config=otherHtmlLoaderConfig`:
```js
module.exports = {
...
module: {
rules: [
{
test: /\.html$/,
use: [ "html-loader?config=otherHtmlLoaderConfig" ]
}
]
},
otherHtmlLoaderConfig: {
...
}
};
```
### Export into HTML files
A very common scenario is exporting the HTML into their own _.html_ file, to
serve them directly instead of injecting with javascript. This can be achieved
with a combination of 3 loaders:
- [file-loader](https://github.com/webpack/file-loader)
- [extract-loader](https://github.com/peerigon/extract-loader)
- html-loader
The html-loader will parse the URLs, require the images and everything you
expect. The extract loader will parse the javascript back into a proper html
file, ensuring images are required and point to proper path, and the file loader
will write the _.html_ file for you. Example:
```js
{
test: /\.html$/,
use: [ 'file-loader?name=[path][name].[ext]!extract-loader!html-loader' ]
}
```
<h2 align="center">Maintainers</h2>
<table>
<tbody>
<tr>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/18315?v=3">
</br>
<a href="https://github.com/hemanth">Hemanth</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/8420490?v=3">
</br>
<a href="https://github.com/d3viant0ne">Joshua Wiens</a>
</td>
<td align="center">
<img width="150" height="150" src="https://avatars.githubusercontent.com/u/5419992?v=3">
</br>
<a href="https://github.com/michael-ciniawsky">Michael Ciniawsky</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/6542274?v=3">
</br>
<a href="https://github.com/imvetri">Imvetri</a>
</td>
</tr>
<tr>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/1520965?v=3">
</br>
<a href="https://github.com/andreicek">Andrei Crnković</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/3367801?v=3">
</br>
<a href="https://github.com/abouthiroppy">Yuta Hiroto</a>
</td>
<td align="center">
<img width="150" height="150" src="https://avatars.githubusercontent.com/u/80044?v=3">
</br>
<a href="https://github.com/petrunov">Vesselin Petrunov</a>
</td>
<td align="center">
<img width="150" height="150"
src="https://avatars.githubusercontent.com/u/973543?v=3">
</br>
<a href="https://github.com/gajus">Gajus Kuizinas</a>
</td>
</tr>
</tbody>
</table>
[npm]: https://img.shields.io/npm/v/html-loader.svg
[npm-url]: https://npmjs.com/package/html-loader
[deps]: https://david-dm.org/webpack/html-loader.svg
[deps-url]: https://david-dm.org/webpack/html-loader
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
[test]: http://img.shields.io/travis/webpack/html-loader.svg
[test-url]: https://travis-ci.org/webpack/html-loader
[cover]: https://codecov.io/gh/webpack/html-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack/html-loader
+141
View File
@@ -0,0 +1,141 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var htmlMinifier = require("html-minifier");
var attrParse = require("./lib/attributesParser");
var loaderUtils = require("loader-utils");
var url = require("url");
var assign = require("object-assign");
var compile = require("es6-templates").compile;
function randomIdent() {
return "xxxHTMLLINKxxx" + Math.random() + Math.random() + "xxx";
}
function getLoaderConfig(context) {
var query = loaderUtils.getOptions(context) || {};
var configKey = query.config || 'htmlLoader';
var config = context.options && context.options.hasOwnProperty(configKey) ? context.options[configKey] : {};
delete query.config;
return assign(query, config);
}
module.exports = function(content) {
this.cacheable && this.cacheable();
var config = getLoaderConfig(this);
var attributes = ["img:src"];
if(config.attrs !== undefined) {
if(typeof config.attrs === "string")
attributes = config.attrs.split(" ");
else if(Array.isArray(config.attrs))
attributes = config.attrs;
else if(config.attrs === false)
attributes = [];
else
throw new Error("Invalid value to config parameter attrs");
}
var root = config.root;
var links = attrParse(content, function(tag, attr) {
return attributes.indexOf(tag + ":" + attr) >= 0;
});
links.reverse();
var data = {};
content = [content];
links.forEach(function(link) {
if(!loaderUtils.isUrlRequest(link.value, root)) return;
var uri = url.parse(link.value);
if (uri.hash !== null && uri.hash !== undefined) {
uri.hash = null;
link.value = uri.format();
link.length = link.value.length;
}
do {
var ident = randomIdent();
} while(data[ident]);
data[ident] = link.value;
var x = content.pop();
content.push(x.substr(link.start + link.length));
content.push(ident);
content.push(x.substr(0, link.start));
});
content.reverse();
content = content.join("");
if (config.interpolate === 'require'){
var reg = /\$\{require\([^)]*\)\}/g;
var result;
var reqList = [];
while(result = reg.exec(content)){
reqList.push({
length : result[0].length,
start : result.index,
value : result[0]
})
}
reqList.reverse();
content = [content];
reqList.forEach(function(link) {
var x = content.pop();
do {
var ident = randomIdent();
} while(data[ident]);
data[ident] = link.value.substring(11,link.length - 3)
content.push(x.substr(link.start + link.length));
content.push(ident);
content.push(x.substr(0, link.start));
});
content.reverse();
content = content.join("");
}
if(typeof config.minimize === "boolean" ? config.minimize : this.minimize) {
var minimizeOptions = assign({}, config);
[
"removeComments",
"removeCommentsFromCDATA",
"removeCDATASectionsFromCDATA",
"collapseWhitespace",
"conservativeCollapse",
"removeAttributeQuotes",
"useShortDoctype",
"keepClosingSlash",
"minifyJS",
"minifyCSS",
"removeScriptTypeAttributes",
"removeStyleTypeAttributes",
].forEach(function(name) {
if(typeof minimizeOptions[name] === "undefined") {
minimizeOptions[name] = true;
}
});
content = htmlMinifier.minify(content, minimizeOptions);
}
if(config.interpolate && config.interpolate !== 'require') {
content = compile('`' + content + '`').code;
} else {
content = JSON.stringify(content);
}
var exportsString = "module.exports = ";
if (config.exportAsDefault) {
exportsString = "exports.default = ";
} else if (config.exportAsEs6Default) {
exportsString = "export default ";
}
return exportsString + content.replace(/xxxHTMLLINKxxx[0-9\.]+xxx/g, function(match) {
if(!data[match]) return match;
return '" + require(' + JSON.stringify(loaderUtils.urlToRequest(data[match], root)) + ') + "';
}) + ";";
}
+42
View File
@@ -0,0 +1,42 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var Parser = require("fastparse");
var processMatch = function(match, strUntilValue, name, value, index) {
if(!this.isRelevantTagAttr(this.currentTag, name)) return;
this.results.push({
start: index + strUntilValue.length,
length: value.length,
value: value
});
};
var parser = new Parser({
outside: {
"<!--.*?-->": true,
"<![CDATA[.*?]]>": true,
"<[!\\?].*?>": true,
"<\/[^>]+>": true,
"<([a-zA-Z\\-:]+)\\s*": function(match, tagName) {
this.currentTag = tagName;
return "inside";
}
},
inside: {
"\\s+": true, // eat up whitespace
">": "outside", // end of attributes
"(([0-9a-zA-Z\\-:]+)\\s*=\\s*\")([^\"]*)\"": processMatch,
"(([0-9a-zA-Z\\-:]+)\\s*=\\s*\')([^\']*)\'": processMatch,
"(([0-9a-zA-Z\\-:]+)\\s*=\\s*)([^\\s>]+)": processMatch
}
});
module.exports = function parse(html, isRelevantTagAttr) {
return parser.parse("outside", html, {
currentTag: null,
results: [],
isRelevantTagAttr: isRelevantTagAttr
}).results;
};
+18
View File
@@ -0,0 +1,18 @@
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="1.1.0"></a>
# [1.1.0](https://github.com/webpack/loader-utils/compare/v1.0.4...v1.1.0) (2017-03-16)
### Features
* **automatic-release:** Generation of automatic release ([7484d13](https://github.com/webpack/loader-utils/commit/7484d13))
* **parseQuery:** export parseQuery ([ddf64e4](https://github.com/webpack/loader-utils/commit/ddf64e4))
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+229
View File
@@ -0,0 +1,229 @@
# loader-utils
## Methods
### `getOptions`
Recommended way to retrieve the options of a loader invocation:
```javascript
// inside your loader
const options = loaderUtils.getOptions(this);
```
1. If `this.query` is a string:
- Tries to parse the query string and returns a new object
- Throws if it's not a valid query string
2. If `this.query` is object-like, it just returns `this.query`
3. In any other case, it just returns `null`
**Please note:** The returned `options` object is *read-only*. It may be re-used across multiple invocations.
If you pass it on to another library, make sure to make a *deep copy* of it:
```javascript
const options = Object.assign(
{},
loaderUtils.getOptions(this), // it is safe to pass null to Object.assign()
defaultOptions
);
// don't forget nested objects or arrays
options.obj = Object.assign({}, options.obj);
options.arr = options.arr.slice();
someLibrary(options);
```
[clone-deep](https://www.npmjs.com/package/clone-deep) is a good library to make a deep copy of the options.
#### Options as query strings
If the loader options have been passed as loader query string (`loader?some&params`), the string is parsed by using [`parseQuery`](#parsequery).
### `parseQuery`
Parses a passed string (e.g. `loaderContext.resourceQuery`) as a query string, and returns an object.
``` javascript
const params = loaderUtils.parseQuery(this.resourceQuery); // resource: `file?param1=foo`
if (params.param1 === "foo") {
// do something
}
```
The string is parsed like this:
``` text
-> Error
? -> {}
?flag -> { flag: true }
?+flag -> { flag: true }
?-flag -> { flag: false }
?xyz=test -> { xyz: "test" }
?xyz=1 -> { xyz: "1" } // numbers are NOT parsed
?xyz[]=a -> { xyz: ["a"] }
?flag1&flag2 -> { flag1: true, flag2: true }
?+flag1,-flag2 -> { flag1: true, flag2: false }
?xyz[]=a,xyz[]=b -> { xyz: ["a", "b"] }
?a%2C%26b=c%2C%26d -> { "a,&b": "c,&d" }
?{data:{a:1},isJSON5:true} -> { data: { a: 1 }, isJSON5: true }
```
### `stringifyRequest`
Turns a request into a string that can be used inside `require()` or `import` while avoiding absolute paths.
Use it instead of `JSON.stringify(...)` if you're generating code inside a loader.
**Why is this necessary?** Since webpack calculates the hash before module paths are translated into module ids, we must avoid absolute paths to ensure
consistent hashes across different compilations.
This function:
- resolves absolute requests into relative requests if the request and the module are on the same hard drive
- replaces `\` with `/` if the request and the module are on the same hard drive
- won't change the path at all if the request and the module are on different hard drives
- applies `JSON.stringify` to the result
```javascript
loaderUtils.stringifyRequest(this, "./test.js");
// "\"./test.js\""
loaderUtils.stringifyRequest(this, ".\\test.js");
// "\"./test.js\""
loaderUtils.stringifyRequest(this, "test");
// "\"test\""
loaderUtils.stringifyRequest(this, "test/lib/index.js");
// "\"test/lib/index.js\""
loaderUtils.stringifyRequest(this, "otherLoader?andConfig!test?someConfig");
// "\"otherLoader?andConfig!test?someConfig\""
loaderUtils.stringifyRequest(this, require.resolve("test"));
// "\"../node_modules/some-loader/lib/test.js\""
loaderUtils.stringifyRequest(this, "C:\\module\\test.js");
// "\"../../test.js\"" (on Windows, in case the module and the request are on the same drive)
loaderUtils.stringifyRequest(this, "C:\\module\\test.js");
// "\"C:\\module\\test.js\"" (on Windows, in case the module and the request are on different drives)
loaderUtils.stringifyRequest(this, "\\\\network-drive\\test.js");
// "\"\\\\network-drive\\\\test.js\"" (on Windows, in case the module and the request are on different drives)
```
### `urlToRequest`
Converts some resource URL to a webpack module request.
```javascript
const url = "path/to/module.js";
const request = loaderUtils.urlToRequest(url); // "./path/to/module.js"
```
#### Module URLs
Any URL containing a `~` will be interpreted as a module request. Anything after the `~` will be considered the request path.
```javascript
const url = "~path/to/module.js";
const request = loaderUtils.urlToRequest(url); // "path/to/module.js"
```
#### Root-relative URLs
URLs that are root-relative (start with `/`) can be resolved relative to some arbitrary path by using the `root` parameter:
```javascript
const url = "/path/to/module.js";
const root = "./root";
const request = loaderUtils.urlToRequest(url, root); // "./root/path/to/module.js"
```
To convert a root-relative URL into a module URL, specify a `root` value that starts with `~`:
```javascript
const url = "/path/to/module.js";
const root = "~";
const request = loaderUtils.urlToRequest(url, root); // "path/to/module.js"
```
### `interpolateName`
Interpolates a filename template using multiple placeholders and/or a regular expression.
The template and regular expression are set as query params called `name` and `regExp` on the current loader's context.
```javascript
const interpolatedName = loaderUtils.interpolateName(loaderContext, name, options);
```
The following tokens are replaced in the `name` parameter:
* `[ext]` the extension of the resource
* `[name]` the basename of the resource
* `[path]` the path of the resource relative to the `context` query parameter or option.
* `[folder]` the folder of the resource is in.
* `[emoji]` a random emoji representation of `options.content`
* `[emoji:<length>]` same as above, but with a customizable number of emojis
* `[hash]` the hash of `options.content` (Buffer) (by default it's the hex digest of the md5 hash)
* `[<hashType>:hash:<digestType>:<length>]` optionally one can configure
* other `hashType`s, i. e. `sha1`, `md5`, `sha256`, `sha512`
* other `digestType`s, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
* and `length` the length in chars
* `[N]` the N-th match obtained from matching the current file name against `options.regExp`
Examples
``` javascript
// loaderContext.resourcePath = "/app/js/javascript.js"
loaderUtils.interpolateName(loaderContext, "js/[hash].script.[ext]", { content: ... });
// => js/9473fdd0d880a43c21b7778d34872157.script.js
// loaderContext.resourcePath = "/app/page.html"
loaderUtils.interpolateName(loaderContext, "html-[hash:6].html", { content: ... });
// => html-9473fd.html
// loaderContext.resourcePath = "/app/flash.txt"
loaderUtils.interpolateName(loaderContext, "[hash]", { content: ... });
// => c31e9820c001c9c4a86bce33ce43b679
// loaderContext.resourcePath = "/app/img/image.gif"
loaderUtils.interpolateName(loaderContext, "[emoji]", { content: ... });
// => 👍
// loaderContext.resourcePath = "/app/img/image.gif"
loaderUtils.interpolateName(loaderContext, "[emoji:4]", { content: ... });
// => 🙍🏢📤🐝
// loaderContext.resourcePath = "/app/img/image.png"
loaderUtils.interpolateName(loaderContext, "[sha512:hash:base64:7].[ext]", { content: ... });
// => 2BKDTjl.png
// use sha512 hash instead of md5 and with only 7 chars of base64
// loaderContext.resourcePath = "/app/img/myself.png"
// loaderContext.query.name =
loaderUtils.interpolateName(loaderContext, "picture.png");
// => picture.png
// loaderContext.resourcePath = "/app/dir/file.png"
loaderUtils.interpolateName(loaderContext, "[path][name].[ext]?[hash]", { content: ... });
// => /app/dir/file.png?9473fdd0d880a43c21b7778d34872157
// loaderContext.resourcePath = "/app/js/page-home.js"
loaderUtils.interpolateName(loaderContext, "script-[1].[ext]", { regExp: "page-(.*)\\.js", content: ... });
// => script-home.js
```
### `getHashDigest`
``` javascript
const digestString = loaderUtils.getHashDigest(buffer, hashType, digestType, maxLength);
```
* `buffer` the content that should be hashed
* `hashType` one of `sha1`, `md5`, `sha256`, `sha512` or any other node.js supported hash type
* `digestType` one of `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
* `maxLength` the maximum length in chars
## License
MIT (http://www.opensource.org/licenses/mit-license.php)
@@ -0,0 +1,13 @@
"use strict";
function getCurrentRequest(loaderContext) {
if(loaderContext.currentRequest)
return loaderContext.currentRequest;
const request = loaderContext.loaders
.slice(loaderContext.loaderIndex)
.map(obj => obj.request)
.concat([loaderContext.resource]);
return request.join("!");
}
module.exports = getCurrentRequest;
@@ -0,0 +1,53 @@
"use strict";
const baseEncodeTables = {
26: "abcdefghijklmnopqrstuvwxyz",
32: "123456789abcdefghjkmnpqrstuvwxyz", // no 0lio
36: "0123456789abcdefghijklmnopqrstuvwxyz",
49: "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ", // no lIO
52: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
58: "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ", // no 0lIO
62: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
64: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
};
function encodeBufferToBase(buffer, base) {
const encodeTable = baseEncodeTables[base];
if(!encodeTable) throw new Error("Unknown encoding base" + base);
const readLength = buffer.length;
const Big = require("big.js");
Big.RM = Big.DP = 0;
let b = new Big(0);
for(let i = readLength - 1; i >= 0; i--) {
b = b.times(256).plus(buffer[i]);
}
let output = "";
while(b.gt(0)) {
output = encodeTable[b.mod(base)] + output;
b = b.div(base);
}
Big.DP = 20;
Big.RM = 1;
return output;
}
function getHashDigest(buffer, hashType, digestType, maxLength) {
hashType = hashType || "md5";
maxLength = maxLength || 9999;
const hash = require("crypto").createHash(hashType);
hash.update(buffer);
if(digestType === "base26" || digestType === "base32" || digestType === "base36" ||
digestType === "base49" || digestType === "base52" || digestType === "base58" ||
digestType === "base62" || digestType === "base64") {
return encodeBufferToBase(hash.digest(), digestType.substr(4)).substr(0, maxLength);
} else {
return hash.digest(digestType || "hex").substr(0, maxLength);
}
}
module.exports = getHashDigest;
+17
View File
@@ -0,0 +1,17 @@
"use strict";
const parseQuery = require("./parseQuery");
function getOptions(loaderContext) {
const query = loaderContext.query;
if(typeof query === "string" && query !== "") {
return parseQuery(loaderContext.query);
}
if(!query || typeof query !== "object") {
// Not object-like queries are not supported.
return null;
}
return query;
}
module.exports = getOptions;
@@ -0,0 +1,13 @@
"use strict";
function getRemainingRequest(loaderContext) {
if(loaderContext.remainingRequest)
return loaderContext.remainingRequest;
const request = loaderContext.loaders
.slice(loaderContext.loaderIndex + 1)
.map(obj => obj.request)
.concat([loaderContext.resource]);
return request.join("!");
}
module.exports = getRemainingRequest;
+23
View File
@@ -0,0 +1,23 @@
"use strict";
const getOptions = require("./getOptions");
const parseQuery = require("./parseQuery");
const stringifyRequest = require("./stringifyRequest");
const getRemainingRequest = require("./getRemainingRequest");
const getCurrentRequest = require("./getCurrentRequest");
const isUrlRequest = require("./isUrlRequest");
const urlToRequest = require("./urlToRequest");
const parseString = require("./parseString");
const getHashDigest = require("./getHashDigest");
const interpolateName = require("./interpolateName");
exports.getOptions = getOptions;
exports.parseQuery = parseQuery;
exports.stringifyRequest = stringifyRequest;
exports.getRemainingRequest = getRemainingRequest;
exports.getCurrentRequest = getCurrentRequest;
exports.isUrlRequest = isUrlRequest;
exports.urlToRequest = urlToRequest;
exports.parseString = parseString;
exports.getHashDigest = getHashDigest;
exports.interpolateName = interpolateName;
@@ -0,0 +1,95 @@
"use strict";
const path = require("path");
const emojisList = require("emojis-list");
const getHashDigest = require("./getHashDigest");
const emojiRegex = /[\uD800-\uDFFF]./;
const emojiList = emojisList.filter(emoji => emojiRegex.test(emoji));
const emojiCache = {};
function encodeStringToEmoji(content, length) {
if(emojiCache[content]) return emojiCache[content];
length = length || 1;
const emojis = [];
do {
const index = Math.floor(Math.random() * emojiList.length);
emojis.push(emojiList[index]);
emojiList.splice(index, 1);
} while(--length > 0);
const emojiEncoding = emojis.join("");
emojiCache[content] = emojiEncoding;
return emojiEncoding;
}
function interpolateName(loaderContext, name, options) {
let filename;
if(typeof name === "function") {
filename = name(loaderContext.resourcePath);
} else {
filename = name || "[hash].[ext]";
}
const context = options.context;
const content = options.content;
const regExp = options.regExp;
let ext = "bin";
let basename = "file";
let directory = "";
let folder = "";
if(loaderContext.resourcePath) {
const parsed = path.parse(loaderContext.resourcePath);
let resourcePath = loaderContext.resourcePath;
if(parsed.ext) {
ext = parsed.ext.substr(1);
}
if(parsed.dir) {
basename = parsed.name;
resourcePath = parsed.dir + path.sep;
}
if(typeof context !== "undefined") {
directory = path.relative(context, resourcePath + "_").replace(/\\/g, "/").replace(/\.\.(\/)?/g, "_$1");
directory = directory.substr(0, directory.length - 1);
} else {
directory = resourcePath.replace(/\\/g, "/").replace(/\.\.(\/)?/g, "_$1");
}
if(directory.length === 1) {
directory = "";
} else if(directory.length > 1) {
folder = path.basename(directory);
}
}
let url = filename;
if(content) {
// Match hash template
url = url
.replace(
/\[(?:(\w+):)?hash(?::([a-z]+\d*))?(?::(\d+))?\]/ig,
(all, hashType, digestType, maxLength) => getHashDigest(content, hashType, digestType, parseInt(maxLength, 10))
)
.replace(
/\[emoji(?::(\d+))?\]/ig,
(all, length) => encodeStringToEmoji(content, length)
);
}
url = url
.replace(/\[ext\]/ig, () => ext)
.replace(/\[name\]/ig, () => basename)
.replace(/\[path\]/ig, () => directory)
.replace(/\[folder\]/ig, () => folder);
if(regExp && loaderContext.resourcePath) {
const match = loaderContext.resourcePath.match(new RegExp(regExp));
match && match.forEach((matched, i) => {
url = url.replace(
new RegExp("\\[" + i + "\\]", "ig"),
matched
);
});
}
if(typeof loaderContext.options === "object" && typeof loaderContext.options.customInterpolateName === "function") {
url = loaderContext.options.customInterpolateName.call(loaderContext, url, name, options);
}
return url;
}
module.exports = interpolateName;
+14
View File
@@ -0,0 +1,14 @@
"use strict";
function isUrlRequest(url, root) {
// An URL is not an request if
// 1. it's a Data Url
// 2. it's an absolute url or and protocol-relative
// 3. it's some kind of url for a template
if(/^data:|^chrome-extension:|^(https?:)?\/\/|^[\{\}\[\]#*;,'§\$%&\(=?`´\^°<>]/.test(url)) return false;
// 4. It's also not an request if root isn't set and it's a root-relative url
if((root === undefined || root === false) && /^\//.test(url)) return false;
return true;
}
module.exports = isUrlRequest;
+54
View File
@@ -0,0 +1,54 @@
"use strict";
const JSON5 = require("json5");
const specialValues = {
"null": null,
"true": true,
"false": false
};
function parseQuery(query) {
if(query.substr(0, 1) !== "?") {
throw new Error("A valid query string passed to parseQuery should begin with '?'");
}
query = query.substr(1);
if(!query) {
return {};
}
if(query.substr(0, 1) === "{" && query.substr(-1) === "}") {
return JSON5.parse(query);
}
const queryArgs = query.split(/[,&]/g);
const result = {};
queryArgs.forEach(arg => {
const idx = arg.indexOf("=");
if(idx >= 0) {
let name = arg.substr(0, idx);
let value = decodeURIComponent(arg.substr(idx + 1));
if(specialValues.hasOwnProperty(value)) {
value = specialValues[value];
}
if(name.substr(-2) === "[]") {
name = decodeURIComponent(name.substr(0, name.length - 2));
if(!Array.isArray(result[name]))
result[name] = [];
result[name].push(value);
} else {
name = decodeURIComponent(name);
result[name] = value;
}
} else {
if(arg.substr(0, 1) === "-") {
result[decodeURIComponent(arg.substr(1))] = false;
} else if(arg.substr(0, 1) === "+") {
result[decodeURIComponent(arg.substr(1))] = true;
} else {
result[decodeURIComponent(arg)] = true;
}
}
});
return result;
}
module.exports = parseQuery;
+19
View File
@@ -0,0 +1,19 @@
"use strict";
function parseString(str) {
try {
if(str[0] === "\"") return JSON.parse(str);
if(str[0] === "'" && str.substr(str.length - 1) === "'") {
return parseString(
str
.replace(/\\.|"/g, x => x === "\"" ? "\\\"" : x)
.replace(/^'|'$/g, "\"")
);
}
return JSON.parse("\"" + str + "\"");
} catch(e) {
return str;
}
}
module.exports = parseString;
@@ -0,0 +1,40 @@
"use strict";
const path = require("path");
const matchRelativePath = /^\.\.?[/\\]/;
function isAbsolutePath(str) {
return path.posix.isAbsolute(str) || path.win32.isAbsolute(str);
}
function isRelativePath(str) {
return matchRelativePath.test(str);
}
function stringifyRequest(loaderContext, request) {
const splitted = request.split("!");
const context = loaderContext.context || (loaderContext.options && loaderContext.options.context);
return JSON.stringify(splitted.map(part => {
// First, separate singlePath from query, because the query might contain paths again
const splittedPart = part.match(/^(.*?)(\?.*)/);
let singlePath = splittedPart ? splittedPart[1] : part;
const query = splittedPart ? splittedPart[2] : "";
if(isAbsolutePath(singlePath) && context) {
singlePath = path.relative(context, singlePath);
if(isAbsolutePath(singlePath)) {
// If singlePath still matches an absolute path, singlePath was on a different drive than context.
// In this case, we leave the path platform-specific without replacing any separators.
// @see https://github.com/webpack/loader-utils/pull/14
return singlePath + query;
}
if(isRelativePath(singlePath) === false) {
// Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
singlePath = "./" + singlePath;
}
}
return singlePath.replace(/\\/g, "/") + query;
}).join("!"));
}
module.exports = stringifyRequest;
+49
View File
@@ -0,0 +1,49 @@
"use strict";
// we can't use path.win32.isAbsolute because it also matches paths starting with a forward slash
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
function urlToRequest(url, root) {
const moduleRequestRegex = /^[^?]*~/;
let request;
if(matchNativeWin32Path.test(url)) {
// absolute windows path, keep it
request = url;
} else if(root !== undefined && root !== false && /^\//.test(url)) {
// if root is set and the url is root-relative
switch(typeof root) {
// 1. root is a string: root is prefixed to the url
case "string":
// special case: `~` roots convert to module request
if(moduleRequestRegex.test(root)) {
request = root.replace(/([^~\/])$/, "$1/") + url.slice(1);
} else {
request = root + url;
}
break;
// 2. root is `true`: absolute paths are allowed
// *nix only, windows-style absolute paths are always allowed as they doesn't start with a `/`
case "boolean":
request = url;
break;
default:
throw new Error("Unexpected parameters to loader-utils 'urlToRequest': url = " + url + ", root = " + root + ".");
}
} else if(/^\.\.?\//.test(url)) {
// A relative url stays
request = url;
} else {
// every other url is threaded like a relative url
request = "./" + url;
}
// A `~` makes the url an module
if(moduleRequestRegex.test(request)) {
request = request.replace(moduleRequestRegex, "");
}
return request;
}
module.exports = urlToRequest;
+109
View File
@@ -0,0 +1,109 @@
{
"_args": [
[
{
"raw": "loader-utils@^1.0.2",
"scope": null,
"escapedName": "loader-utils",
"name": "loader-utils",
"rawSpec": "^1.0.2",
"spec": ">=1.0.2 <2.0.0",
"type": "range"
},
"c:\\xampp\\htdocs\\laravel\\node_modules\\html-loader"
]
],
"_from": "loader-utils@>=1.0.2 <2.0.0",
"_id": "loader-utils@1.1.0",
"_inCache": true,
"_location": "/html-loader/loader-utils",
"_nodeVersion": "7.7.3",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/loader-utils-1.1.0.tgz_1489673126296_0.2887681087013334"
},
"_npmUser": {
"name": "jhnns",
"email": "mail@johannesewald.de"
},
"_npmVersion": "4.1.2",
"_phantomChildren": {},
"_requested": {
"raw": "loader-utils@^1.0.2",
"scope": null,
"escapedName": "loader-utils",
"name": "loader-utils",
"rawSpec": "^1.0.2",
"spec": ">=1.0.2 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/html-loader"
],
"_resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
"_shasum": "c98aef488bcceda2ffb5e2de646d6a754429f5cd",
"_shrinkwrap": null,
"_spec": "loader-utils@^1.0.2",
"_where": "c:\\xampp\\htdocs\\laravel\\node_modules\\html-loader",
"author": {
"name": "Tobias Koppers @sokra"
},
"bugs": {
"url": "https://github.com/webpack/loader-utils/issues"
},
"dependencies": {
"big.js": "^3.1.3",
"emojis-list": "^2.0.0",
"json5": "^0.5.0"
},
"description": "utils for webpack loaders",
"devDependencies": {
"coveralls": "^2.11.2",
"eslint": "^3.15.0",
"eslint-plugin-node": "^4.0.1",
"istanbul": "^0.3.14",
"mocha": "^1.21.4",
"standard-version": "^4.0.0"
},
"directories": {},
"dist": {
"shasum": "c98aef488bcceda2ffb5e2de646d6a754429f5cd",
"tarball": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz"
},
"engines": {
"node": ">=4.0.0"
},
"files": [
"lib"
],
"gitHead": "a5602addda0c5e98e70d067b8dd050d5e4153f1d",
"homepage": "https://github.com/webpack/loader-utils#readme",
"license": "MIT",
"main": "lib/index.js",
"maintainers": [
{
"name": "jhnns",
"email": "mail@johannesewald.de"
},
{
"name": "sokra",
"email": "tobias.koppers@googlemail.com"
}
],
"name": "loader-utils",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/webpack/loader-utils.git"
},
"scripts": {
"cover": "istanbul cover -x *.runtime.js node_modules/mocha/bin/_mocha",
"lint": "eslint lib test",
"posttest": "npm run lint",
"release": "npm test && standard-version",
"test": "mocha",
"travis": "npm run cover -- --report lcovonly"
},
"version": "1.1.0"
}
+136
View File
@@ -0,0 +1,136 @@
{
"_args": [
[
{
"raw": "html-loader@^0.4.4",
"scope": null,
"escapedName": "html-loader",
"name": "html-loader",
"rawSpec": "^0.4.4",
"spec": ">=0.4.4 <0.5.0",
"type": "range"
},
"c:\\xampp\\htdocs\\laravel\\node_modules\\laravel-mix"
]
],
"_from": "html-loader@>=0.4.4 <0.5.0",
"_id": "html-loader@0.4.5",
"_inCache": true,
"_location": "/html-loader",
"_nodeVersion": "6.9.5",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/html-loader-0.4.5.tgz_1487960864573_0.6131426664069295"
},
"_npmUser": {
"name": "d3viant0ne",
"email": "wiens.joshua@gmail.com"
},
"_npmVersion": "3.10.10",
"_phantomChildren": {
"big.js": "3.1.3",
"emojis-list": "2.1.0",
"json5": "0.5.1"
},
"_requested": {
"raw": "html-loader@^0.4.4",
"scope": null,
"escapedName": "html-loader",
"name": "html-loader",
"rawSpec": "^0.4.4",
"spec": ">=0.4.4 <0.5.0",
"type": "range"
},
"_requiredBy": [
"/laravel-mix"
],
"_resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.4.5.tgz",
"_shasum": "5fbcd87cd63a5c49a7fce2fe56f425e05729c68c",
"_shrinkwrap": null,
"_spec": "html-loader@^0.4.4",
"_where": "c:\\xampp\\htdocs\\laravel\\node_modules\\laravel-mix",
"author": {
"name": "Tobias Koppers @sokra"
},
"bugs": {
"url": "https://github.com/webpack/html-loader/issues"
},
"dependencies": {
"es6-templates": "^0.2.2",
"fastparse": "^1.1.1",
"html-minifier": "^3.0.1",
"loader-utils": "^1.0.2",
"object-assign": "^4.1.0"
},
"description": "html loader module for webpack",
"devDependencies": {
"beautify-lint": "^1.0.4",
"codecov.io": "^0.1.6",
"eslint": "^3.1.1",
"istanbul": "^0.4.4",
"js-beautify": "^1.6.3",
"mocha": "^2.5.3",
"should": "^10.0.0"
},
"directories": {},
"dist": {
"shasum": "5fbcd87cd63a5c49a7fce2fe56f425e05729c68c",
"tarball": "https://registry.npmjs.org/html-loader/-/html-loader-0.4.5.tgz"
},
"gitHead": "90c7b60d41a0af76019dbefa91d45dab90fbdd1e",
"homepage": "https://github.com/webpack/html-loader#readme",
"license": "MIT",
"maintainers": [
{
"name": "bebraw",
"email": "bebraw@gmail.com"
},
{
"name": "d3viant0ne",
"email": "wiens.joshua@gmail.com"
},
{
"name": "ericclemmons",
"email": "eric@smarterspam.com"
},
{
"name": "hemanth",
"email": "hemanth.hm@gmail.com"
},
{
"name": "jhnns",
"email": "mail@johannesewald.de"
},
{
"name": "peerigon",
"email": "developers@peerigon.com"
},
{
"name": "sokra",
"email": "tobias.koppers@googlemail.com"
},
{
"name": "thelarkinn",
"email": "sean.larkin@cuw.edu"
}
],
"name": "html-loader",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/webpack/html-loader.git"
},
"scripts": {
"beautify": "beautify-rewrite lib/**/*.js hot/**/*.js bin/**/*.js benchmark/*.js test/*.js",
"beautify-lint": "beautify-lint lib/**/*.js hot/**/*.js bin/**/*.js benchmark/*.js test/*.js",
"cover": "istanbul cover -x *.runtime.js node_modules/mocha/bin/_mocha",
"lint": "eslint lib bin hot",
"postcover": "npm run lint && npm run beautify-lint",
"pretest": "npm run lint && npm run beautify-lint",
"publish-patch": "npm run lint && npm run beautify-lint && mocha && npm version patch && git push && git push --tags && npm publish",
"test": "mocha --harmony --full-trace --check-leaks",
"travis": "npm run cover -- --report lcovonly"
},
"version": "0.4.5"
}