pug-loader
Advanced tools
Comparing version 1.0.2 to 2.0.0
226
index.js
@@ -1,81 +0,161 @@ | ||
'use strict'; | ||
var path = require("path"); | ||
var dirname = path.dirname; | ||
var loaderUtils = require("loader-utils"); | ||
var nodeResolve = require("resolve").sync; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var walk = require('pug-walk'); | ||
module.exports = function(source) { | ||
this.cacheable && this.cacheable(); | ||
module.exports = load; | ||
function load(ast, options) { | ||
load.validateOptions(options); | ||
// clone the ast | ||
ast = JSON.parse(JSON.stringify(ast)); | ||
return walk(ast, function (node) { | ||
if (node.str === undefined) { | ||
if (node.type === 'Include' || node.type === 'RawInclude' || node.type === 'Extends') { | ||
var file = node.file; | ||
if (file.type !== 'FileReference') { | ||
throw new Error('Expected file.type to be "FileReference"'); | ||
} | ||
var path, str; | ||
try { | ||
path = (options.resolve || load.resolve)(file.path, file.filename, options); | ||
file.fullPath = path; | ||
str = (options.read || load.read)(path, options); | ||
} catch (ex) { | ||
ex.message += '\n at ' + node.filename + ' line ' + node.line; | ||
throw ex; | ||
} | ||
file.str = str; | ||
if (node.type === 'Extends' || node.type === 'Include') { | ||
file.ast = load.string(str, path, options); | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
var modulePaths = {}; | ||
modulePaths.pug = require.resolve("pug"); | ||
modulePaths.load = nodeResolve("pug-load", {basedir: dirname(modulePaths.pug)}); | ||
modulePaths.runtime = nodeResolve("pug-runtime", {basedir: dirname(modulePaths.pug)}); | ||
modulePaths.walk = nodeResolve("pug-walk", {basedir: dirname(modulePaths.pug)}); | ||
load.string = function loadString(str, filename, options) { | ||
load.validateOptions(options); | ||
var tokens = options.lex(str, filename); | ||
var ast = options.parse(tokens, filename); | ||
return load(ast, options); | ||
}; | ||
load.file = function loadFile(filename, options) { | ||
load.validateOptions(options); | ||
var str = (options.read || load.read)(filename, options); | ||
return load.string(str, filename, options); | ||
} | ||
var pug = require(modulePaths.pug); | ||
var load = require(modulePaths.load); | ||
var walk = require(modulePaths.walk); | ||
load.resolve = function resolve(filename, source, options) { | ||
filename = filename.trim(); | ||
if (filename[0] !== '/' && !source) | ||
throw new Error('the "filename" option is required to use includes and extends with "relative" paths'); | ||
var req = loaderUtils.getRemainingRequest(this).replace(/^!/, ""); | ||
if (filename[0] === '/' && !options.basedir) | ||
throw new Error('the "basedir" option is required to use includes and extends with "absolute" paths'); | ||
var query = loaderUtils.parseQuery(this.query); | ||
filename = path.join(filename[0] === '/' ? options.basedir : path.dirname(source.trim()), filename); | ||
var loadModule = this.loadModule; | ||
var resolve = this.resolve; | ||
var loaderContext = this; | ||
var callback; | ||
return filename; | ||
}; | ||
load.read = function read(filename, options) { | ||
return fs.readFileSync(filename, 'utf8'); | ||
}; | ||
var fileContents = {}; | ||
var filePaths = {}; | ||
load.validateOptions = function validateOptions(options) { | ||
if (typeof options !== 'object') { | ||
throw new TypeError('options must be an object'); | ||
} | ||
if (typeof options.lex !== 'function') { | ||
throw new TypeError('options.lex must be a function'); | ||
} | ||
if (typeof options.parse !== 'function') { | ||
throw new TypeError('options.parse must be a function'); | ||
} | ||
if (options.resolve && typeof options.resolve !== 'function') { | ||
throw new TypeError('options.resolve must be a function'); | ||
} | ||
if (options.read && typeof options.read !== 'function') { | ||
throw new TypeError('options.read must be a function'); | ||
} | ||
}; | ||
var missingFileMode = false; | ||
function getFileContent(context, request) { | ||
request = loaderUtils.urlToRequest(request, query.root) | ||
var baseRequest = request; | ||
var filePath; | ||
filePath = filePaths[context + " " + request]; | ||
if(filePath) return filePath; | ||
var isSync = true; | ||
resolve(context, request, function(err, _request) { | ||
if(err) { | ||
resolve(context, request, function(err2, _request) { | ||
if(err2) return callback(err2); | ||
request = _request; | ||
next(); | ||
}); | ||
return; | ||
} | ||
request = _request; | ||
next(); | ||
function next() { | ||
loadModule("-!" + path.join(__dirname, "stringify.loader.js") + "!" + request, function(err, source) { | ||
if(err) return callback(err); | ||
filePaths[context + " " + baseRequest] = request; | ||
fileContents[request] = JSON.parse(source); | ||
if(!isSync) { | ||
run(); | ||
} | ||
}); | ||
} | ||
}); | ||
filePath = filePaths[context + " " + baseRequest]; | ||
if(filePath) return filePath; | ||
isSync = false; | ||
missingFileMode = true; | ||
throw "continue"; | ||
} | ||
var plugin = loadModule ? { | ||
postParse: function (ast) { | ||
return walk(ast, function (node) { | ||
if ([ | ||
"Mixin", | ||
"MixinBlock", | ||
"NamedBlock" | ||
].indexOf(node.type) !== -1) { | ||
ast._mustBeInlined = true; | ||
} | ||
}); | ||
}, | ||
resolve: function (request, source) { | ||
if (!callback) { | ||
callback = loaderContext.async(); | ||
} | ||
if (!callback) { | ||
return load.resolve(request, source); | ||
} | ||
var context = dirname(source.split("!").pop()); | ||
return getFileContent(context, request); | ||
}, | ||
read: function (path) { | ||
if (!callback) { | ||
return load.read(path); | ||
} | ||
return fileContents[path]; | ||
}, | ||
postLoad: function postLoad(ast) { | ||
return walk(ast, function (node, replace) { | ||
if (node.file && node.file.ast) { | ||
postLoad(node.file.ast); | ||
} | ||
if (node.type === "Include") { | ||
if (node.file.ast._mustBeInlined) { | ||
ast._mustBeInlined = true; | ||
} | ||
} | ||
}, function (node, replace) { | ||
if (node.type === "Include" && !(node.block && node.block.nodes.length) && !node.file.ast._mustBeInlined) { | ||
replace({ | ||
type: "Code", | ||
val: "require(" + loaderUtils.stringifyRequest(loaderContext, node.file.fullPath) + ").call(this, locals)", | ||
buffer: true, | ||
mustEscape: false, | ||
isInline: false, | ||
line: node.line, | ||
filename: node.filename | ||
}); | ||
} | ||
}); | ||
} | ||
} : {}; | ||
run(); | ||
function run() { | ||
try { | ||
var tmplFunc = pug.compileClient(source, { | ||
filename: req, | ||
doctype: query.doctype || "html", | ||
pretty: query.pretty, | ||
self: query.self, | ||
compileDebug: loaderContext.debug || false, | ||
globals: ["require"].concat(query.globals || []), | ||
name: "template", | ||
inlineRuntimeFunctions: false, | ||
plugins: [ | ||
plugin | ||
].concat(query.plugins || []) | ||
}); | ||
} catch(e) { | ||
if(missingFileMode) { | ||
// Ignore, it'll continue after async action | ||
missingFileMode = false; | ||
return; | ||
} | ||
throw e; | ||
} | ||
var runtime = "var pug = require(" + loaderUtils.stringifyRequest(loaderContext, "!" + modulePaths.runtime) + ");\n\n"; | ||
loaderContext.callback(null, runtime + tmplFunc.toString() + ";\nmodule.exports = template;"); | ||
} | ||
} |
{ | ||
"name": "pug-loader", | ||
"version": "1.0.2", | ||
"description": "The pug loader is responsible for loading the depenendencies of a given pug file.", | ||
"keywords": [ | ||
"pug" | ||
], | ||
"version": "2.0.0", | ||
"author": "Tobias Koppers @sokra", | ||
"description": "Pug loader module for Webpack", | ||
"dependencies": { | ||
"pug-walk": "0.0.3" | ||
"loader-utils": "~0.2.5", | ||
"resolve": "^1.1.7" | ||
}, | ||
"peerDependencies": { | ||
"pug": ">=2.0.0-beta3 <3" | ||
}, | ||
"devDependencies": { | ||
"pug-lexer": "^1.0.0", | ||
"pug-parser": "^1.0.0" | ||
"mocha": "*", | ||
"pug": "^2.0.0-beta4", | ||
"should": "*" | ||
}, | ||
"scripts": { | ||
"test": "node test" | ||
"test": "mocha -R spec" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/pugjs/pug-loader.git" | ||
"url": "git://github.com/pug/pug-loader.git" | ||
}, | ||
"author": "ForbesLindesay", | ||
"license": "MIT" | ||
} | ||
} |
124
README.md
@@ -1,103 +0,63 @@ | ||
# pug-loader | ||
# Pug loader for Webpack | ||
The pug loader is responsible for loading the depenendencies of a given pug file. It adds `fullPath` and `str` properties to every `Include` and `Extends` node. It also adds an `ast` property to any `Include` nodes that are loading pug and any `Extends` nodes. It then recursively loads the dependencies of any of those included files. | ||
## Usage | ||
[![Build Status](https://img.shields.io/travis/pugjs/pug-loader/master.svg)](https://travis-ci.org/pugjs/pug-loader) | ||
[![Dependency Status](https://img.shields.io/david/pugjs/pug-loader.svg)](https://david-dm.org/pugjs/pug-loader) | ||
[![NPM version](https://img.shields.io/npm/v/pug-loader.svg)](https://www.npmjs.org/package/pug-loader) | ||
``` javascript | ||
var template = require("pug!./file.pug"); | ||
// => returns file.pug content as template function | ||
## Installation | ||
// or, if you've bound .pug to pug-loader | ||
var template = require("./file.pug"); | ||
npm install pug-loader | ||
var locals = { /* ... */ }; | ||
## Usage | ||
```js | ||
var load = require('pug-load'); | ||
var html = template(locals); | ||
// => the rendered HTML | ||
``` | ||
### `load(ast, options)` | ||
### `load.string(str, filename, options)` | ||
### `load.file(filename, options)` | ||
For more information on how to use Webpack loaders, check the [official documentation][using-loaders]. | ||
Loads all dependencies of the Pug AST. `load.string` and `load.file` are syntactic sugar that parses the string or file instead of you doing it yourself. | ||
### Legacy `.jade` files | ||
`options` may contain the following properties: | ||
pug-loader fully supports `.jade` files. Just use pug-loader with `.jade` files as you would with a `.pug` file. | ||
- `lex` (function): **(required)** the lexer used | ||
- `parse` (function): **(required)** the parser used | ||
- `resolve` (function): a function used to override `load.resolve`. Defaults to `load.resolve`. | ||
- `read` (function): a function used to override `load.read`. Defaults to `load.read`. | ||
- `basedir` (string): the base directory of absolute inclusion. This is **required** when absolute inclusion (file name starts with `'/'`) is used. Defaults to undefined. | ||
### Includes | ||
The `options` object is passed to `load.resolve` and `load.read`, or equivalently `options.resolve` and `options.read`. | ||
If you are using [includes], you must make sure that `.pug` (and if needed for legacy files, `.jade`) is bound to pug-loader. Check the Webpack documentation on how to do that for [CLI][module-bind-cli] and for [configuration files][module-bind-config]. | ||
### `load.resolve(filename, source, options)` | ||
### Options | ||
Callback used by `pug-load` to resolve the full path of an included or extended file given the path of the source file. | ||
The following options are available to be set as part of the [loader query][query]. They are all mapped directly to Pug options, unless pointed out otherwise. | ||
`filename` is the included file. `source` is the name of the parent file that includes `filename`. | ||
- `doctype` | ||
- Unlike Pug, it defaults to `"html"` if not set | ||
- `globals` | ||
- `self` | ||
- `plugins` | ||
- Note that you cannot specify any Pug plugins implementing `read` or `resolve` hooks, as those are reserved for the loader | ||
- `pretty` | ||
- `root` | ||
- Webpack uses its own file resolving mechanism, so while it is functionally equivalent to the Pug option with the same name, it is implemented differently | ||
This function is not meant to be called from outside of `pug-load`, but rather for you to override. | ||
### Embedded resources | ||
### `load.read(filename, options)` | ||
Try to use `require` for all your embedded resources, to process them with webpack. | ||
Callback used by `pug-load` to return the contents of a file. | ||
```pug | ||
div | ||
img(src=require("./my/image.png")) | ||
``` | ||
`filename` is the file to read. | ||
Remember, you need to configure loaders for these file types too. You might be interested in the [file loader][file-loader]. | ||
This function is not meant to be called from outside of `pug-load`, but rather for you to override. | ||
## License | ||
### `load.validateOptions(options)` | ||
[MIT][mit] | ||
Callback used `pug-load` to ensure the options object is valid. If your overriden `load.resolve` or `load.read` uses a different `options` scheme, you will need to override this function as well. | ||
This function is not meant to be called from outside of `pug-load`, but rather for you to override. | ||
### Example | ||
```js | ||
var fs = require('fs'); | ||
var lex = require('pug-lexer'); | ||
var parse = require('pug-parser'); | ||
var load = require('pug-loader'); | ||
// you can do everything very manually | ||
var str = fs.readFileSync('bar.pug', 'utf8'); | ||
var ast = load(parse(lex(str, 'bar.pug'), 'bar.pug'), { | ||
lex: lex, | ||
parse: parse, | ||
resolve: function (filename, source, options) { | ||
console.log('"' + filename + '" file requested from "' + source + '".'); | ||
return load.resolve(filename, source, options); | ||
} | ||
}); | ||
// or you can do all that in just two steps | ||
var str = fs.readFileSync('bar.pug', 'utf8'); | ||
var ast = load.string(str, 'bar.pug', { | ||
lex: lex, | ||
parse: parse, | ||
resolve: function (filename, source, options) { | ||
console.log('"' + filename + '" file requested from "' + source + '".'); | ||
return load.resolve(filename, source, options); | ||
} | ||
}); | ||
// or you can do all that in only one step | ||
var ast = load.file('bar.pug', { | ||
lex: lex, | ||
parse: parse, | ||
resolve: function (filename, source, options) { | ||
console.log('"' + filename + '" file requested from "' + source + '".'); | ||
return load.resolve(filename, source, options); | ||
} | ||
}); | ||
``` | ||
## License | ||
MIT | ||
[file-loader]: https://github.com/webpack/file-loader | ||
[includes]: http://jade-lang.com/reference/includes/ | ||
[mit]: https://www.opensource.org/licenses/mit-license.php | ||
[module-bind-cli]: https://webpack.github.io/docs/using-loaders.html#configuration | ||
[module-bind-config]: https://webpack.github.io/docs/using-loaders.html#cli | ||
[query]: https://webpack.github.io/docs/using-loaders.html#query-parameters | ||
[using-loaders]: https://webpack.github.io/docs/using-loaders.html |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
12338
24
242
0
3
3
64
7
2
+ Addedloader-utils@~0.2.5
+ Addedresolve@^1.1.7
+ Added@types/babel-types@7.0.15(transitive)
+ Added@types/babylon@6.16.9(transitive)
+ Addedacorn@3.3.04.0.13(transitive)
+ Addedacorn-globals@3.1.0(transitive)
+ Addedalign-text@0.1.4(transitive)
+ Addedasap@2.0.6(transitive)
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedbabel-types@6.26.0(transitive)
+ Addedbabylon@6.18.0(transitive)
+ Addedbig.js@3.2.0(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedcamelcase@1.2.1(transitive)
+ Addedcenter-align@0.1.3(transitive)
+ Addedcharacter-parser@2.2.0(transitive)
+ Addedclean-css@4.2.4(transitive)
+ Addedcliui@2.1.0(transitive)
+ Addedconstantinople@3.1.2(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addeddefine-data-property@1.1.4(transitive)
+ Addeddoctypes@1.1.0(transitive)
+ Addedemojis-list@2.1.0(transitive)
+ Addedes-define-property@1.0.0(transitive)
+ Addedes-errors@1.3.0(transitive)
+ Addedesutils@2.0.3(transitive)
+ Addedfunction-bind@1.1.2(transitive)
+ Addedget-intrinsic@1.2.4(transitive)
+ Addedgopd@1.0.1(transitive)
+ Addedhas-property-descriptors@1.0.2(transitive)
+ Addedhas-proto@1.0.3(transitive)
+ Addedhas-symbols@1.0.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedhasown@2.0.2(transitive)
+ Addedis-buffer@1.1.6(transitive)
+ Addedis-core-module@2.15.1(transitive)
+ Addedis-expression@3.0.0(transitive)
+ Addedis-promise@2.2.2(transitive)
+ Addedis-regex@1.1.4(transitive)
+ Addedjs-stringify@1.0.2(transitive)
+ Addedjson5@0.5.1(transitive)
+ Addedjstransformer@1.0.0(transitive)
+ Addedkind-of@3.2.2(transitive)
+ Addedlazy-cache@1.0.4(transitive)
+ Addedloader-utils@0.2.17(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedlongest@1.0.1(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedpromise@7.3.1(transitive)
+ Addedpug@2.0.4(transitive)
+ Addedpug-attrs@2.0.4(transitive)
+ Addedpug-code-gen@2.0.3(transitive)
+ Addedpug-error@1.3.3(transitive)
+ Addedpug-filters@3.1.1(transitive)
+ Addedpug-lexer@4.1.0(transitive)
+ Addedpug-linker@3.0.6(transitive)
+ Addedpug-load@2.0.12(transitive)
+ Addedpug-parser@5.0.1(transitive)
+ Addedpug-runtime@2.0.5(transitive)
+ Addedpug-strip-comments@1.0.4(transitive)
+ Addedpug-walk@1.1.8(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
+ Addedrepeat-string@1.6.1(transitive)
+ Addedresolve@1.22.8(transitive)
+ Addedright-align@0.1.3(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedsource-map@0.5.70.6.1(transitive)
+ Addedsupports-preserve-symlinks-flag@1.0.0(transitive)
+ Addedto-fast-properties@1.0.3(transitive)
+ Addedtoken-stream@0.0.1(transitive)
+ Addeduglify-js@2.8.29(transitive)
+ Addeduglify-to-browserify@1.0.2(transitive)
+ Addedvoid-elements@2.0.1(transitive)
+ Addedwindow-size@0.1.0(transitive)
+ Addedwith@5.1.1(transitive)
+ Addedwordwrap@0.0.2(transitive)
+ Addedyargs@3.10.0(transitive)
- Removedpug-walk@0.0.3
- Removedpug-walk@0.0.3(transitive)