mithril-render-loader
Advanced tools
Comparing version 0.2.0 to 0.6.0
168
index.js
/* eslint no-invalid-this: 0 */ | ||
require("mithril/test-utils/browserMock")(global); | ||
const m = require("mithril"); | ||
const chalk = require("chalk"); | ||
const render = require("mithril-node-render"); | ||
const vm2 = require("vm2"); | ||
const requireHook = ` | ||
var path = require("path"); | ||
var hook = require("require-hook"); | ||
hook.attach(path.resolve()); | ||
`; | ||
function logTime(message, startTime, endTime) { | ||
console.log(`${chalk.cyan("mithril-render-loader")} -- ${message}: ${chalk.blue((endTime - startTime) / 1000)}s`); | ||
} | ||
const requireExport = ` | ||
require('exportRequires')(hook.getData()); | ||
hook.detach(path.resolve()); | ||
`; | ||
function mithrilRenderLoader(view) { | ||
// prevents some(!) messed up states - the loader is currently fast enough enough | ||
this.cacheable(false); | ||
function mithrilRenderLoader(view) { | ||
// the render-mithril operation is async, which is a good thing most of the times | ||
const timeStart = Date.now(); | ||
// the render-mithril operation is async | ||
var done = this.async(); | ||
// options | ||
const o = Object.assign({ | ||
profile: false, // log build times | ||
model: null, // data passed to component | ||
"export": false, // use module.exports or return result as string (html-loader) | ||
// mithril-render-node options @see https://github.com/MithrilJS/mithril-node-render#options | ||
escapeAttributeValue: false, // either a boolean or a function (value) => value to parse attributes | ||
escapeString: true, // A filter function for string nodes | ||
strict: false // true for xml/xhtml | ||
}, this.query); | ||
// require dependencies | ||
let dependencies; | ||
if (o.model === null) { | ||
this.emitWarning("property 'model' is not for mithril-render"); | ||
o.model = {}; | ||
} | ||
const vm = new vm2.NodeVM({ | ||
console: "inherit", | ||
sandbox: { | ||
}, | ||
require: { | ||
external: true, | ||
builtin: ["fs", "path", "module"], | ||
root: "./", | ||
mock: { | ||
exportRequires(list) { | ||
dependencies = list | ||
.map((info) => info.absPath) | ||
.filter((path) => typeof path === "string"); | ||
// pass a uid to mithril component | ||
o.model.ID = `${this.resourcePath}${Date.now()}${Math.random()}`; | ||
o.model.COMPONENT_ID = this.resourcePath; | ||
// prototype - webpack require | ||
const requests = []; | ||
const self = this; | ||
function resolveModule(id, requestPath) { | ||
return new Promise((resolve, reject) => { | ||
// console.log(`mithril require ${requestPath}`); | ||
self.loadModule(requestPath, (err, source, sourceMap, module) => { | ||
if (err) { | ||
console.log("ERROR", err.message); | ||
return reject(err); | ||
} | ||
} | ||
} | ||
}); | ||
// module.exports = __webpack_public_path__ + "intro-mobile-f825065fb480b357.jpg"; | ||
source = source.replace(/^module\.exports[^"]*/, ""); | ||
if (/^".*"$/.test(source)) { | ||
source.replace(/(^"|"$)/g, ""); | ||
} | ||
console.log("RESOLVED", source); | ||
return resolve({ id, source }); | ||
}); | ||
}); | ||
} | ||
// run the contents in nodejs, hooking into require | ||
try { | ||
view = vm.run(`${requireHook}${view}${requireExport}`, this.resource); | ||
} catch (e) { | ||
return done(e); | ||
global.resolve = function (requestPath) { | ||
const id = `{{${requestPath}${Date.now()}${Math.random()}`; | ||
requests.push(resolveModule(id, requestPath)); | ||
return id; | ||
}; | ||
const dependenciesBefore = Object.keys(require.cache); | ||
view = require(this.resourcePath); | ||
let timeResolve; | ||
// gather renderer options | ||
const renderOptions = { strict: o.strict }; | ||
if (o.escapeAttributeValue === false) { | ||
renderOptions.escapeAttributeValue = (value) => value; | ||
} else if (typeof o.escapeAttributeValue === "function") { | ||
renderOptions.escapeAttributeValue = o.escapeAttributeValue; | ||
} | ||
if (o.escapeString === false) { | ||
renderOptions.escapeString = (value) => value; | ||
} else if (typeof o.escapeString === "function") { | ||
renderOptions.escapeString = o.escapeString; | ||
} | ||
dependencies.forEach((filepath) => { | ||
// watch file dependencies | ||
this.addDependency(filepath); | ||
// and remove them from cache in order to be reread next run (webpack-dev-server) | ||
delete require.cache[filepath]; | ||
}); | ||
// fetch the required data and render the component | ||
render(m(view, o.model), renderOptions) | ||
.then((html) => { | ||
timeResolve = Date.now(); | ||
o.profile && logTime(`render component ${this.resource}`, timeStart, timeResolve); | ||
// global.resolve = undefined; | ||
// fetch the required data | ||
const model = this.query.model; | ||
// and render the component | ||
render(m(view, model)).then((html) => { | ||
console.log("RESULT", html); | ||
done(null, `module.exports = ${JSON.stringify(html)}`); | ||
}) | ||
.catch(done); | ||
const dependencies = []; | ||
Object.keys(require.cache).forEach((filepath) => { | ||
if (dependenciesBefore.indexOf(filepath) === -1) { | ||
dependencies.push(filepath); | ||
} | ||
}); | ||
// clear cache AFTER main file has been compiled | ||
dependencies.forEach((filepath) => { | ||
// watch file dependencies | ||
this.addDependency(filepath); | ||
// and remove them from cache in order to be reread next run (webpack-dev-server) | ||
delete require.cache[filepath]; | ||
}); | ||
// tryout | ||
this.addDependency(this.resourcePath); | ||
return html; | ||
}) | ||
.then((html) => Promise | ||
.all(requests) | ||
.then((results) => { | ||
o.profile && logTime(`resolve webpack requires ${this.resource}`, timeResolve, Date.now()); | ||
results.forEach((data) => { | ||
console.log("insert", data.source); | ||
html = html.replace(data.id, data.source); | ||
}); | ||
return html; | ||
}) | ||
) | ||
.then((html) => { | ||
o.profile && logTime(`total time ${this.resource}`, timeStart, Date.now()); | ||
if (o.export) { // if no html loader | ||
return done(null, `module.exports = ${JSON.stringify(html)}`); | ||
} | ||
return done(null, html); | ||
}) | ||
.catch(done); | ||
} | ||
@@ -68,0 +138,0 @@ |
{ | ||
"name": "mithril-render-loader", | ||
"version": "0.2.0", | ||
"version": "0.6.0", | ||
"description": "", | ||
@@ -14,7 +14,9 @@ "main": "index.js", | ||
"dependencies": { | ||
"chalk": "^2.2.0", | ||
"mithril": "^1.1.5", | ||
"mithril-node-render": "^2.2.0", | ||
"require-hook": "^0.1.2", | ||
"vm2": "^3.5.2" | ||
"mithril-node-render": "^2.2.0" | ||
}, | ||
"publishConfig": { | ||
"registry": "http://registry.npmjs.org" | ||
}, | ||
"devDependencies": { | ||
@@ -24,2 +26,3 @@ "eslint": "^3.19.0", | ||
"file-loader": "^1.1.5", | ||
"html-loader": "^0.5.1", | ||
"webpack": "^3.8.1", | ||
@@ -26,0 +29,0 @@ "webpack-dev-server": "^2.9.3" |
@@ -46,2 +46,11 @@ # mithril-render-loader | ||
{ | ||
loader: "html-loader", | ||
options: { | ||
minimize: false, // deactivate minimize. It destroys valid inline css syntax | ||
interpolate: false, | ||
minifyCSS: false, // bugged | ||
root: __dirname, | ||
} | ||
}, | ||
{ | ||
loader: "mithril-render-loader", | ||
@@ -48,0 +57,0 @@ options: { |
@@ -46,2 +46,5 @@ const path = require("path"); | ||
{ | ||
loader: "html-loader" | ||
}, | ||
{ | ||
loader: path.join(__dirname, "index.js"), | ||
@@ -48,0 +51,0 @@ options: { |
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
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
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
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
22497
3
210
72
6
1
+ Addedchalk@^2.2.0
+ Addedansi-styles@3.2.1(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedcolor-convert@1.9.3(transitive)
+ Addedcolor-name@1.1.3(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedsupports-color@5.5.0(transitive)
- Removedrequire-hook@^0.1.2
- Removedvm2@^3.5.2
- Removedacorn@8.14.0(transitive)
- Removedacorn-walk@8.3.4(transitive)
- Removedlodash@4.17.21(transitive)
- Removedrequire-hook@0.1.2(transitive)
- Removedvm2@3.9.19(transitive)