mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #150 - Provide option to prevent writing compiled templates to disk
This commit is contained in:
parent
f85cdcae9f
commit
370ac4b3ab
@ -19,12 +19,26 @@ var req = require; // Fool code inspectors used by client-side bundles
|
|||||||
var nodePath = require('path');
|
var nodePath = require('path');
|
||||||
|
|
||||||
var defaultOptions = {
|
var defaultOptions = {
|
||||||
|
/**
|
||||||
|
* Set of tag names that should automatically have whitespace preserved.
|
||||||
|
* Alternatively, if value is `true` then whitespace will be preserved
|
||||||
|
* for all tags.
|
||||||
|
*/
|
||||||
preserveWhitespace: {
|
preserveWhitespace: {
|
||||||
'pre': true,
|
'pre': true,
|
||||||
'textarea': true,
|
'textarea': true,
|
||||||
'script': true
|
'script': true
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Set of tag names that should be allowed to be rendered as a self-closing
|
||||||
|
* XML tag. A self-closing tag will only be rendered if the tag has no nested
|
||||||
|
* content. HTML doesn't allow self-closing tags so you should likely
|
||||||
|
* never use this.
|
||||||
|
*/
|
||||||
allowSelfClosing: {},
|
allowSelfClosing: {},
|
||||||
|
/**
|
||||||
|
* Set of tag names that should be rendered with a start tag only.
|
||||||
|
*/
|
||||||
startTagOnly: {
|
startTagOnly: {
|
||||||
'img': true,
|
'img': true,
|
||||||
'br': true,
|
'br': true,
|
||||||
@ -33,7 +47,22 @@ var defaultOptions = {
|
|||||||
'link': true,
|
'link': true,
|
||||||
'hr': true
|
'hr': true
|
||||||
},
|
},
|
||||||
checkUpToDate: true
|
/**
|
||||||
|
* If true, then the compiler will check the disk to see if a previously compiled
|
||||||
|
* template is the same age or newer than the source template. If so, the previously
|
||||||
|
* compiled template will be loaded. Otherwise, the template will be recompiled
|
||||||
|
* and saved to disk.
|
||||||
|
*
|
||||||
|
* If false, the template will always be recompiled. If `writeToDisk` is false
|
||||||
|
* then this option will be ignored.
|
||||||
|
*/
|
||||||
|
checkUpToDate: true,
|
||||||
|
/**
|
||||||
|
* If true (the default) then compiled templates will be written to disk. If false,
|
||||||
|
* compiled templates will not be written to disk (i.e., no `.marko.js` file will
|
||||||
|
* be generated)
|
||||||
|
*/
|
||||||
|
writeToDisk: true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.MARKO_CLEAN === '' || process.env.MARKO_CLEAN === 'true') {
|
if (process.env.MARKO_CLEAN === '' || process.env.MARKO_CLEAN === 'true') {
|
||||||
|
|||||||
@ -131,4 +131,100 @@ Example usage:
|
|||||||
```javascript
|
```javascript
|
||||||
var template = require('./template.marko');
|
var template = require('./template.marko');
|
||||||
template.stream({ name: 'Frank' }).pipe(process.stdout);
|
template.stream({ name: 'Frank' }).pipe(process.stdout);
|
||||||
|
```
|
||||||
|
|
||||||
|
# require('marko/compiler')
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### createCompiler(path, options) : TemplateCompiler
|
||||||
|
|
||||||
|
Creates a compiler for a given template path and given options.
|
||||||
|
|
||||||
|
### compile(src, path, options, callback)
|
||||||
|
|
||||||
|
Compiles a template given the loaded template source, the file system path of the source template and options.
|
||||||
|
Currently, compilation is synchronous so the callback is optional. In the future, we may allow asynchronous
|
||||||
|
compilation.
|
||||||
|
|
||||||
|
The result will be the compiled JavaScript source code.
|
||||||
|
|
||||||
|
### compileFile(path, options, callback)
|
||||||
|
|
||||||
|
Compiles a template given the loaded template source, the file system path of the source template and options.
|
||||||
|
Currently, compilation is synchronous so the callback is optional. In the future, we may allow asynchronous
|
||||||
|
compilation.
|
||||||
|
|
||||||
|
The result will be the compiled JavaScript source code.
|
||||||
|
|
||||||
|
### getLastModified(path, options, callback)
|
||||||
|
|
||||||
|
Compiles a template given the loaded template source, the file system path of the source template and options.
|
||||||
|
Currently, this method is synchronous so the callback is optional. In the future, we may allow this method to be asynchronous.
|
||||||
|
|
||||||
|
Returns the last modified time as a number.
|
||||||
|
|
||||||
|
### clearCaches()
|
||||||
|
|
||||||
|
Clears any internal caches used by the compiler. Needed for hot-reloading.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
### defaultOptions
|
||||||
|
|
||||||
|
The default options used by the compiler. These options can be changed as shown in the following sample code:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
require('marko/compiler').defaultOptions.writeToDisk = false;
|
||||||
|
```
|
||||||
|
|
||||||
|
Default options:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set of tag names that should automatically have whitespace preserved.
|
||||||
|
* Alternatively, if value is `true` then whitespace will be preserved
|
||||||
|
* for all tags.
|
||||||
|
*/
|
||||||
|
preserveWhitespace: {
|
||||||
|
'pre': true,
|
||||||
|
'textarea': true,
|
||||||
|
'script': true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Set of tag names that should be allowed to be rendered as a self-closing
|
||||||
|
* XML tag. A self-closing tag will only be rendered if the tag has no nested
|
||||||
|
* content. HTML doesn't allow self-closing tags so you should likely
|
||||||
|
* never use this.
|
||||||
|
*/
|
||||||
|
allowSelfClosing: {},
|
||||||
|
/**
|
||||||
|
* Set of tag names that should be rendered with a start tag only.
|
||||||
|
*/
|
||||||
|
startTagOnly: {
|
||||||
|
'img': true,
|
||||||
|
'br': true,
|
||||||
|
'input': true,
|
||||||
|
'meta': true,
|
||||||
|
'link': true,
|
||||||
|
'hr': true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* If true, then the compiler will check the disk to see if a previously compiled
|
||||||
|
* template is the same age or newer than the source template. If so, the previously
|
||||||
|
* compiled template will be loaded. Otherwise, the template will be recompiled
|
||||||
|
* and saved to disk.
|
||||||
|
*
|
||||||
|
* If false, the template will always be recompiled. If `writeToDisk` is false
|
||||||
|
* then this option will be ignored.
|
||||||
|
*/
|
||||||
|
checkUpToDate: true,
|
||||||
|
/**
|
||||||
|
* If true (the default) then compiled templates will be written to disk. If false,
|
||||||
|
* compiled templates will not be written to disk (i.e., no `.marko.js` file will
|
||||||
|
* be generated)
|
||||||
|
*/
|
||||||
|
writeToDisk: true
|
||||||
|
}
|
||||||
```
|
```
|
||||||
@ -1,12 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 eBay Software Foundation
|
* Copyright 2011 eBay Software Foundation
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -20,28 +20,43 @@ var fs = require('fs');
|
|||||||
var fsReadOptions = { encoding: 'utf8' };
|
var fsReadOptions = { encoding: 'utf8' };
|
||||||
|
|
||||||
function compile(templatePath, markoCompiler, compilerOptions) {
|
function compile(templatePath, markoCompiler, compilerOptions) {
|
||||||
|
|
||||||
var targetDir = path.dirname(templatePath);
|
|
||||||
|
|
||||||
var targetFile = templatePath + '.js';
|
|
||||||
var compiler = markoCompiler.createCompiler(templatePath, compilerOptions);
|
var compiler = markoCompiler.createCompiler(templatePath, compilerOptions);
|
||||||
var isUpToDate = compiler.checkUpToDate(targetFile);
|
|
||||||
|
var writeToDisk = compilerOptions.writeToDisk
|
||||||
|
if (writeToDisk == null) {
|
||||||
|
writeToDisk = markoCompiler.defaultOptions.writeToDisk;
|
||||||
|
}
|
||||||
|
var templateSrc;
|
||||||
var compiledSrc;
|
var compiledSrc;
|
||||||
|
|
||||||
if (isUpToDate) {
|
if (writeToDisk === false) {
|
||||||
compiledSrc = fs.readFileSync(targetFile, fsReadOptions);
|
// Don't write the compiled template to disk. Instead, load it
|
||||||
|
// directly from the compiled source using the internals of the
|
||||||
|
// Node.js module loading system.
|
||||||
|
templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
||||||
|
compiledSrc = compiler.compile(templateSrc);
|
||||||
} else {
|
} else {
|
||||||
var templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
var targetDir = path.dirname(templatePath);
|
||||||
compiledSrc = compiler.compile(templateSrc);
|
|
||||||
|
|
||||||
// Write to a temporary file and move it into place to avoid problems
|
var targetFile = templatePath + '.js';
|
||||||
// assocatiated with multiple processes write to teh same file. We only
|
|
||||||
// write the compiled source code to disk so that stack traces will
|
var isUpToDate = compiler.checkUpToDate(targetFile);
|
||||||
// be accurate.
|
|
||||||
var filename = path.basename(targetFile);
|
if (isUpToDate) {
|
||||||
var tempFile = path.join(targetDir, '.' + process.pid + '.' + Date.now() + '.' + filename);
|
compiledSrc = fs.readFileSync(targetFile, fsReadOptions);
|
||||||
fs.writeFileSync(tempFile, compiledSrc, fsReadOptions);
|
} else {
|
||||||
fs.renameSync(tempFile, targetFile);
|
templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
||||||
|
compiledSrc = compiler.compile(templateSrc);
|
||||||
|
|
||||||
|
// Write to a temporary file and move it into place to avoid problems
|
||||||
|
// assocatiated with multiple processes write to teh same file. We only
|
||||||
|
// write the compiled source code to disk so that stack traces will
|
||||||
|
// be accurate.
|
||||||
|
var filename = path.basename(targetFile);
|
||||||
|
var tempFile = path.join(targetDir, '.' + process.pid + '.' + Date.now() + '.' + filename);
|
||||||
|
fs.writeFileSync(tempFile, compiledSrc, fsReadOptions);
|
||||||
|
fs.renameSync(tempFile, targetFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We attach a path to the compiled template so that hot reloading will work.
|
// We attach a path to the compiled template so that hot reloading will work.
|
||||||
@ -51,7 +66,7 @@ function compile(templatePath, markoCompiler, compilerOptions) {
|
|||||||
exports.install = function(options) {
|
exports.install = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
var compilerOptions = options.compilerOptions;
|
var compilerOptions = options.compilerOptions || {};
|
||||||
|
|
||||||
var extension = options.extension || '.marko';
|
var extension = options.extension || '.marko';
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@ function loadSource(templatePath, compiledSrc) {
|
|||||||
return templateModule.exports;
|
return templateModule.exports;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function load(templatePath) {
|
function loadFile(templatePath) {
|
||||||
templatePath = nodePath.resolve(cwd, templatePath);
|
templatePath = nodePath.resolve(cwd, templatePath);
|
||||||
var targetDir = nodePath.dirname(templatePath);
|
var targetDir = nodePath.dirname(templatePath);
|
||||||
|
|
||||||
@ -67,6 +67,20 @@ module.exports = function load(templatePath) {
|
|||||||
fs.renameSync(tempFile, targetFile);
|
fs.renameSync(tempFile, targetFile);
|
||||||
|
|
||||||
return require(targetFile);
|
return require(targetFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function load(templatePath) {
|
||||||
|
if (markoCompiler.defaultOptions.writeToDisk === false) {
|
||||||
|
// Don't write the compiled template to disk. Instead, load it
|
||||||
|
// directly from the compiled source using the internals of the
|
||||||
|
// Node.js module loading system.
|
||||||
|
var compiler = markoCompiler.createCompiler(templatePath);
|
||||||
|
var templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
||||||
|
var compiledSrc = compiler.compile(templateSrc);
|
||||||
|
return loadSource(templatePath, compiledSrc);
|
||||||
|
} else {
|
||||||
|
return loadFile(templatePath);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.loadSource = loadSource;
|
module.exports.loadSource = loadSource;
|
||||||
|
|||||||
@ -5,6 +5,7 @@ var expect = require('chai').expect;
|
|||||||
var nodePath = require('path');
|
var nodePath = require('path');
|
||||||
var marko = require('../');
|
var marko = require('../');
|
||||||
var through = require('through');
|
var through = require('through');
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
require('../node-require').install();
|
require('../node-require').install();
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ describe('marko/api' , function() {
|
|||||||
greeting: 'Greetings'
|
greeting: 'Greetings'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var output = template.renderSync(data)
|
var output = template.renderSync(data);
|
||||||
expect(output).to.equal('Greetings John!');
|
expect(output).to.equal('Greetings John!');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -259,7 +260,7 @@ describe('marko/api' , function() {
|
|||||||
|
|
||||||
it('should allow a template to be loaded from a compiled JS module', function(done) {
|
it('should allow a template to be loaded from a compiled JS module', function(done) {
|
||||||
// Load the JS file to ensure the hello.marko.js file is created
|
// Load the JS file to ensure the hello.marko.js file is created
|
||||||
marko.load(nodePath.join(__dirname, 'fixtures/templates/api-tests/hello.marko'))
|
marko.load(nodePath.join(__dirname, 'fixtures/templates/api-tests/hello.marko'));
|
||||||
|
|
||||||
var templateModule = require(nodePath.join(__dirname, 'fixtures/templates/api-tests/hello.marko.js'));
|
var templateModule = require(nodePath.join(__dirname, 'fixtures/templates/api-tests/hello.marko.js'));
|
||||||
|
|
||||||
@ -336,4 +337,61 @@ describe('marko/api' , function() {
|
|||||||
stream);
|
stream);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should write compiled templates to disk by default when using the Node.js require extension', function() {
|
||||||
|
var compiledPath;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var templatePath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko');
|
||||||
|
compiledPath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko.js');
|
||||||
|
var template = require(templatePath);
|
||||||
|
expect(fs.existsSync(compiledPath)).to.equal(true);
|
||||||
|
expect(template.renderSync({name: 'Frank'})).to.equal('Hello Frank!');
|
||||||
|
} finally {
|
||||||
|
fs.unlinkSync(compiledPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should write compiled templates to disk by default when using load', function() {
|
||||||
|
|
||||||
|
var compiledPath;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var templatePath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko');
|
||||||
|
compiledPath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko.js');
|
||||||
|
var template = marko.load(templatePath);
|
||||||
|
expect(fs.existsSync(compiledPath)).to.equal(true);
|
||||||
|
expect(template.renderSync({name: 'Frank'})).to.equal('Hello Frank!');
|
||||||
|
} finally {
|
||||||
|
fs.unlinkSync(compiledPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow compiled templates to not be written to disk when using the Node.js require extension', function() {
|
||||||
|
require('../compiler').defaultOptions.writeToDisk = false;
|
||||||
|
try {
|
||||||
|
var templatePath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko');
|
||||||
|
var compiledPath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko.js');
|
||||||
|
var template = require(templatePath);
|
||||||
|
expect(fs.existsSync(compiledPath)).to.equal(false);
|
||||||
|
expect(template.render).to.be.a('function');
|
||||||
|
expect(template.renderSync({name: 'Frank'})).to.equal('Hello Frank!');
|
||||||
|
} finally {
|
||||||
|
require('../compiler').defaultOptions.writeToDisk = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should allow compiled templates to not be written to disk when using load', function() {
|
||||||
|
require('../compiler').defaultOptions.writeToDisk = false;
|
||||||
|
try {
|
||||||
|
var templatePath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko');
|
||||||
|
var compiledPath = nodePath.join(__dirname, 'fixtures/write-to-disk/template.marko.js');
|
||||||
|
var template = marko.load(templatePath);
|
||||||
|
expect(fs.existsSync(compiledPath)).to.equal(false);
|
||||||
|
expect(template.render).to.be.a('function');
|
||||||
|
expect(template.renderSync({name: 'Frank'})).to.equal('Hello Frank!');
|
||||||
|
} finally {
|
||||||
|
require('../compiler').defaultOptions.writeToDisk = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
1
test/fixtures/write-to-disk/template.marko
vendored
Normal file
1
test/fixtures/write-to-disk/template.marko
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello ${data.name}!
|
||||||
Loading…
x
Reference in New Issue
Block a user