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 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: {
|
||||
'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,
|
||||
@ -33,7 +47,22 @@ var defaultOptions = {
|
||||
'link': 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') {
|
||||
|
||||
@ -131,4 +131,100 @@ Example usage:
|
||||
```javascript
|
||||
var template = require('./template.marko');
|
||||
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
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@ -20,28 +20,43 @@ var fs = require('fs');
|
||||
var fsReadOptions = { encoding: 'utf8' };
|
||||
|
||||
function compile(templatePath, markoCompiler, compilerOptions) {
|
||||
|
||||
var targetDir = path.dirname(templatePath);
|
||||
|
||||
var targetFile = templatePath + '.js';
|
||||
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;
|
||||
|
||||
if (isUpToDate) {
|
||||
compiledSrc = fs.readFileSync(targetFile, fsReadOptions);
|
||||
if (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.
|
||||
templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
||||
compiledSrc = compiler.compile(templateSrc);
|
||||
} else {
|
||||
var templateSrc = fs.readFileSync(templatePath, fsReadOptions);
|
||||
compiledSrc = compiler.compile(templateSrc);
|
||||
var targetDir = path.dirname(templatePath);
|
||||
|
||||
// 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);
|
||||
var targetFile = templatePath + '.js';
|
||||
|
||||
var isUpToDate = compiler.checkUpToDate(targetFile);
|
||||
|
||||
if (isUpToDate) {
|
||||
compiledSrc = fs.readFileSync(targetFile, fsReadOptions);
|
||||
} else {
|
||||
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.
|
||||
@ -51,7 +66,7 @@ function compile(templatePath, markoCompiler, compilerOptions) {
|
||||
exports.install = function(options) {
|
||||
options = options || {};
|
||||
|
||||
var compilerOptions = options.compilerOptions;
|
||||
var compilerOptions = options.compilerOptions || {};
|
||||
|
||||
var extension = options.extension || '.marko';
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ function loadSource(templatePath, compiledSrc) {
|
||||
return templateModule.exports;
|
||||
}
|
||||
|
||||
module.exports = function load(templatePath) {
|
||||
function loadFile(templatePath) {
|
||||
templatePath = nodePath.resolve(cwd, templatePath);
|
||||
var targetDir = nodePath.dirname(templatePath);
|
||||
|
||||
@ -67,6 +67,20 @@ module.exports = function load(templatePath) {
|
||||
fs.renameSync(tempFile, 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;
|
||||
|
||||
@ -5,6 +5,7 @@ var expect = require('chai').expect;
|
||||
var nodePath = require('path');
|
||||
var marko = require('../');
|
||||
var through = require('through');
|
||||
var fs = require('fs');
|
||||
|
||||
require('../node-require').install();
|
||||
|
||||
@ -203,7 +204,7 @@ describe('marko/api' , function() {
|
||||
greeting: 'Greetings'
|
||||
}
|
||||
};
|
||||
var output = template.renderSync(data)
|
||||
var output = template.renderSync(data);
|
||||
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) {
|
||||
// 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'));
|
||||
|
||||
@ -336,4 +337,61 @@ describe('marko/api' , function() {
|
||||
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