gulp-include
Advanced tools
Comparing version 2.4.0 to 2.4.1
# Changelog | ||
#### 2.4.1 | ||
* Post merge code cleanup by [KenEucker](https://github.com/KenEucker) | ||
* Updated README with Gulp 4 examples | ||
* Added documentation and tests for separateInputs | ||
#### 2.4.0 | ||
* Lots of community fixes graceously assembled and merged by [KenEucker](https://github.com/KenEucker) | ||
* Dependencies update after three years. | ||
* The plugin now supports both gulp 3 and gulp version 4. | ||
* Merged support for separated includes between files, by [PFight](https://github.com/PFight) | ||
@@ -6,0 +14,0 @@ #### 2.3.1 |
539
index.js
var fs = require('fs'), | ||
path = require('path'), | ||
es = require('event-stream'), | ||
glob = require('glob'), | ||
PluginError = require('plugin-error'), | ||
colors = require('ansi-colors'), | ||
applySourceMap = require('vinyl-sourcemaps-apply'), | ||
stripBom = require('strip-bom'); | ||
path = require('path'), | ||
es = require('event-stream'), | ||
glob = require('glob'), | ||
PluginError = require('plugin-error'), | ||
colors = require('ansi-colors'), | ||
applySourceMap = require('vinyl-sourcemaps-apply'), | ||
stripBom = require('strip-bom'); | ||
module.exports = function (params) { | ||
params = params || {}; | ||
params = params || {}; | ||
var SourceMapGenerator = require('source-map').SourceMapGenerator; | ||
var SourceMapConsumer = require('source-map').SourceMapConsumer; | ||
var SourceMapGenerator = require('source-map').SourceMapGenerator; | ||
var SourceMapConsumer = require('source-map').SourceMapConsumer; | ||
var extensions = null, // The extension to be searched after | ||
globalIncludedFiles = [], // For track of what files have been included over all files | ||
includePaths = false, // The paths to be searched | ||
hardFail = false, // Throw error when no match | ||
separateInputs = false; // Process each input file separately when using `require` logic. | ||
var extensions = null, // The extension to be searched after | ||
globalIncludedFiles = [], // To track what files have been included over all files | ||
includePaths = false, // The paths to be searched | ||
hardFail = false, // Throw error when no match | ||
separateInputs = false; // Process each input file separately when using `require` directive | ||
// Check for includepaths in the params | ||
if (params.includePaths) { | ||
if (typeof params.includePaths == "string") { | ||
// Arrayify the string | ||
includePaths = [params.includePaths]; | ||
} else if (Array.isArray(params.includePaths)) { | ||
// Set this array to the includepaths | ||
includePaths = params.includePaths; | ||
} | ||
} | ||
// Check for includepaths in the params | ||
if (params.includePaths) { | ||
if (typeof params.includePaths == "string") { | ||
// Arrayify the string | ||
includePaths = [params.includePaths]; | ||
} else if (Array.isArray(params.includePaths)) { | ||
// Set this array to the includepaths | ||
includePaths = params.includePaths; | ||
} | ||
} | ||
if (params.separateInputs) { | ||
separateInputs = true; | ||
} | ||
if (params.separateInputs) { | ||
separateInputs = true; | ||
} | ||
// Toggle error reporting | ||
if (params.hardFail != undefined) { | ||
hardFail = params.hardFail; | ||
} | ||
// Toggle error reporting | ||
if (params.hardFail != undefined) { | ||
hardFail = params.hardFail; | ||
} | ||
if (params.extensions) { | ||
extensions = typeof params.extensions === 'string' ? [params.extensions] : params.extensions; | ||
} | ||
if (params.extensions) { | ||
extensions = typeof params.extensions === 'string' ? [params.extensions] : params.extensions; | ||
} | ||
function include(file, callback) { | ||
var includedFiles = separateInputs ? [] : globalIncludedFiles; | ||
function include(file, callback) { | ||
var includedFiles = separateInputs ? [] : globalIncludedFiles; | ||
if (file.isNull()) { | ||
return callback(null, file); | ||
} | ||
if (file.isNull()) { | ||
return callback(null, file); | ||
} | ||
if (file.isStream()) { | ||
throw new PluginError('gulp-include', 'stream not supported'); | ||
} | ||
if (file.isStream()) { | ||
throw new PluginError('gulp-include', 'stream not supported'); | ||
} | ||
if (file.isBuffer()) { | ||
var result = processInclude(String(file.contents), file.path, file.sourceMap, includedFiles); | ||
file.contents = new Buffer(result.content); | ||
if (file.isBuffer()) { | ||
var result = processInclude(String(file.contents), file.path, file.sourceMap, includedFiles); | ||
file.contents = new Buffer(result.content); | ||
if (file.sourceMap && result.map) { | ||
if (Object.prototype.toString.call(result.map) === '[object String]') { | ||
result.map = JSON.parse(result.map); | ||
} | ||
if (file.sourceMap && result.map) { | ||
if (Object.prototype.toString.call(result.map) === '[object String]') { | ||
result.map = JSON.parse(result.map); | ||
} | ||
// relative-ize the paths in the map | ||
result.map.file = path.relative(file.base, result.map.file); | ||
result.map.sources.forEach(function (source, q) { | ||
result.map.sources[q] = path.relative(file.base, result.map.sources[q]); | ||
}); | ||
// relative-ize the paths in the map | ||
result.map.file = path.relative(file.base, result.map.file); | ||
result.map.sources.forEach(function (source, q) { | ||
result.map.sources[q] = path.relative(file.base, result.map.sources[q]); | ||
}); | ||
applySourceMap(file, result.map); | ||
} | ||
} | ||
applySourceMap(file, result.map); | ||
} | ||
} | ||
callback(null, file); | ||
} | ||
callback(null, file); | ||
} | ||
function processInclude(content, filePath, sourceMap, includedFiles) { | ||
var matches = content.match(/^(\s+)?(\/\/|\/\*|\#|\<\!\-\-)(\s+)?=(\s+)?(include|require)(.+$)/mg); | ||
var relativeBasePath = path.dirname(filePath); | ||
function processInclude(content, filePath, sourceMap, includedFiles) { | ||
var matches = content.match(/^(\s+)?(\/\/|\/\*|\#|\<\!\-\-)(\s+)?=(\s+)?(include|require)(.+$)/mg); | ||
var relativeBasePath = path.dirname(filePath); | ||
if (!matches) return { | ||
content: content, | ||
map: null | ||
}; | ||
if (!matches) return { | ||
content: content, | ||
map: null | ||
}; | ||
// Apply sourcemaps | ||
var map = null, | ||
mapSelf, lastMappedLine, currentPos, insertedLines; | ||
if (sourceMap) { | ||
map = new SourceMapGenerator({ | ||
file: unixStylePath(filePath) | ||
}); | ||
lastMappedLine = 1; | ||
currentPos = 0; | ||
insertedLines = 0; | ||
// Apply sourcemaps | ||
var map = null, | ||
mapSelf, lastMappedLine, currentPos, insertedLines; | ||
if (sourceMap) { | ||
map = new SourceMapGenerator({ | ||
file: unixStylePath(filePath) | ||
}); | ||
lastMappedLine = 1; | ||
currentPos = 0; | ||
insertedLines = 0; | ||
mapSelf = function (currentLine) { // maps current file between matches and after all matches | ||
var currentOrigLine = currentLine - insertedLines; | ||
mapSelf = function (currentLine) { // maps current file between matches and after all matches | ||
var currentOrigLine = currentLine - insertedLines; | ||
for (var q = (currentLine - lastMappedLine); q > 0; q--) { | ||
map.addMapping({ | ||
generated: { | ||
line: currentLine - q, | ||
column: 0 | ||
}, | ||
original: { | ||
line: currentOrigLine - q, | ||
column: 0 | ||
}, | ||
source: filePath | ||
}); | ||
} | ||
for (var q = (currentLine - lastMappedLine); q > 0; q--) { | ||
map.addMapping({ | ||
generated: { | ||
line: currentLine - q, | ||
column: 0 | ||
}, | ||
original: { | ||
line: currentOrigLine - q, | ||
column: 0 | ||
}, | ||
source: filePath | ||
}); | ||
} | ||
lastMappedLine = currentLine; | ||
}; | ||
} | ||
lastMappedLine = currentLine; | ||
}; | ||
} | ||
for (var i = 0; i < matches.length; i++) { | ||
var leadingWhitespaceMatch = matches[i].match(/^\s*/); | ||
var leadingWhitespace = null; | ||
if (leadingWhitespaceMatch) { | ||
leadingWhitespace = leadingWhitespaceMatch[0].replace("\n", ""); | ||
} | ||
for (var i = 0; i < matches.length; i++) { | ||
var leadingWhitespaceMatch = matches[i].match(/^\s*/); | ||
var leadingWhitespace = null; | ||
if (leadingWhitespaceMatch) { | ||
leadingWhitespace = leadingWhitespaceMatch[0].replace("\n", ""); | ||
} | ||
// Remove beginnings, endings and trim. | ||
var includeCommand = matches[i] | ||
.replace(/\s+/g, " ") | ||
.replace(/(\/\/|\/\*|\#|<!--)(\s+)?=(\s+)?/g, "") | ||
.replace(/(\*\/|-->)$/g, "") | ||
.replace(/['"]/g, "") | ||
.trim(); | ||
// Remove beginnings, endings and trim. | ||
var includeCommand = matches[i] | ||
.replace(/\s+/g, " ") | ||
.replace(/(\/\/|\/\*|\#|<!--)(\s+)?=(\s+)?/g, "") | ||
.replace(/(\*\/|-->)$/g, "") | ||
.replace(/['"]/g, "") | ||
.trim(); | ||
var split = includeCommand.split(" "); | ||
var split = includeCommand.split(" "); | ||
var currentLine; | ||
if (sourceMap) { | ||
// get position of current match and get current line number | ||
currentPos = content.indexOf(matches[i], currentPos); | ||
currentLine = currentPos === -1 ? 0 : content.substr(0, currentPos).match(/^/mg).length; | ||
var currentLine; | ||
if (sourceMap) { | ||
// get position of current match and get current line number | ||
currentPos = content.indexOf(matches[i], currentPos); | ||
currentLine = currentPos === -1 ? 0 : content.substr(0, currentPos).match(/^/mg).length; | ||
// sometimes the line matches the leading \n and sometimes it doesn't. wierd. | ||
// in case it does, increment the current line counter | ||
if (leadingWhitespaceMatch[0][0] == '\n') currentLine++; | ||
// sometimes the line matches the leading \n and sometimes it doesn't. wierd. | ||
// in case it does, increment the current line counter | ||
if (leadingWhitespaceMatch[0][0] == '\n') currentLine++; | ||
mapSelf(currentLine); | ||
} | ||
mapSelf(currentLine); | ||
} | ||
// SEARCHING STARTS HERE | ||
// Split the directive and the path | ||
var includeType = split[0]; | ||
// SEARCHING STARTS HERE | ||
// Split the directive and the path | ||
var includeType = split[0]; | ||
// Use glob for file searching | ||
var fileMatches = []; | ||
var includePath = ""; | ||
// Use glob for file searching | ||
var fileMatches = []; | ||
var includePath = ""; | ||
if (includePaths != false) { | ||
// If includepaths are set, search in those folders | ||
for (var y = 0; y < includePaths.length; y++) { | ||
includePath = includePaths[y] + "/" + split[1]; | ||
if (includePaths != false && !isExplicitRelativePath(split[1])) { | ||
// If includepaths are set, search in those folders | ||
for (var y = 0; y < includePaths.length; y++) { | ||
includePath = includePaths[y] + "/" + split[1]; | ||
var globResults = glob.sync(includePath, { | ||
mark: true | ||
}); | ||
fileMatches = fileMatches.concat(globResults); | ||
} | ||
} else { | ||
// Otherwise search relatively | ||
includePath = relativeBasePath + "/" + split[1]; | ||
var globResults = glob.sync(includePath, { | ||
mark: true | ||
}); | ||
fileMatches = globResults; | ||
} | ||
var globResults = glob.sync(includePath, { | ||
mark: true | ||
}); | ||
fileMatches = fileMatches.concat(globResults); | ||
} | ||
} else { | ||
// Otherwise search relatively | ||
includePath = relativeBasePath + "/" + removeRelativePathPrefix(split[1]); | ||
var globResults = glob.sync(includePath, { | ||
mark: true | ||
}); | ||
fileMatches = globResults; | ||
} | ||
if (fileMatches.length < 1) fileNotFoundError(includePath); | ||
if (fileMatches.length < 1) fileNotFoundError(includePath); | ||
var replaceContent = ''; | ||
for (var y = 0; y < fileMatches.length; y++) { | ||
var globbedFilePath = fileMatches[y]; | ||
var replaceContent = ''; | ||
for (var y = 0; y < fileMatches.length; y++) { | ||
var globbedFilePath = fileMatches[y]; | ||
// If directive is of type "require" and file already included, skip to next. | ||
if (includeType == "require" && includedFiles.indexOf(globbedFilePath) > -1) continue; | ||
// If directive is of type "require" and file already included, skip to next. | ||
if (includeType == "require" && includedFiles.indexOf(globbedFilePath) > -1) continue; | ||
// If not in extensions, skip this file | ||
if (!inExtensions(globbedFilePath)) continue; | ||
// If not in extensions, skip this file | ||
if (!inExtensions(globbedFilePath)) continue; | ||
// Get file contents and apply recursive include on result | ||
// Unicode byte order marks are stripped from the start of included files | ||
var fileContents = stripBom(fs.readFileSync(globbedFilePath)); | ||
// Get file contents and apply recursive include on result | ||
// Unicode byte order marks are stripped from the start of included files | ||
var fileContents = stripBom(fs.readFileSync(globbedFilePath)); | ||
var result = processInclude(fileContents.toString(), globbedFilePath, sourceMap, includedFiles); | ||
var resultContent = result.content; | ||
var result = processInclude(fileContents.toString(), globbedFilePath, sourceMap, includedFiles); | ||
var resultContent = result.content; | ||
if (sourceMap) { | ||
var lines = resultContent.match(/^/mg).length; //count lines in result | ||
if (sourceMap) { | ||
var lines = resultContent.match(/^/mg).length; //count lines in result | ||
if (result.map) { // result had a map, merge mappings | ||
if (Object.prototype.toString.call(result.map) === '[object String]') { | ||
result.map = JSON.parse(result.map); | ||
} | ||
if (result.map) { // result had a map, merge mappings | ||
if (Object.prototype.toString.call(result.map) === '[object String]') { | ||
result.map = JSON.parse(result.map); | ||
} | ||
if (result.map.mappings && result.map.mappings.length > 0) { | ||
var resultMap = new SourceMapConsumer(result.map); | ||
resultMap.eachMapping(function (mapping) { | ||
if (!mapping.source) return; | ||
if (result.map.mappings && result.map.mappings.length > 0) { | ||
var resultMap = new SourceMapConsumer(result.map); | ||
resultMap.eachMapping(function (mapping) { | ||
if (!mapping.source) return; | ||
map.addMapping({ | ||
generated: { | ||
line: mapping.generatedLine + currentLine - 1, | ||
column: mapping.generatedColumn + (leadingWhitespace ? leadingWhitespace.length : 0) | ||
}, | ||
original: { | ||
line: mapping.originalLine, | ||
column: mapping.originalColumn | ||
}, | ||
source: mapping.source, | ||
name: mapping.name | ||
}); | ||
}); | ||
map.addMapping({ | ||
generated: { | ||
line: mapping.generatedLine + currentLine - 1, | ||
column: mapping.generatedColumn + (leadingWhitespace ? leadingWhitespace.length : 0) | ||
}, | ||
original: { | ||
line: mapping.originalLine, | ||
column: mapping.originalColumn | ||
}, | ||
source: mapping.source, | ||
name: mapping.name | ||
}); | ||
}); | ||
if (result.map.sourcesContent) { | ||
result.map.sourcesContent.forEach(function (sourceContent, i) { | ||
map.setSourceContent(result.map.sources[i], sourceContent); | ||
}); | ||
} | ||
} | ||
} else { // result was a simple file, map whole file to new location | ||
for (var q = 0; q < lines; q++) { | ||
map.addMapping({ | ||
generated: { | ||
line: currentLine + q, | ||
column: leadingWhitespace ? leadingWhitespace.length : 0 | ||
}, | ||
original: { | ||
line: q + 1, | ||
column: 0 | ||
}, | ||
source: globbedFilePath | ||
}); | ||
} | ||
if (result.map.sourcesContent) { | ||
result.map.sourcesContent.forEach(function (sourceContent, i) { | ||
map.setSourceContent(result.map.sources[i], sourceContent); | ||
}); | ||
} | ||
} | ||
} else { // result was a simple file, map whole file to new location | ||
for (var q = 0; q < lines; q++) { | ||
map.addMapping({ | ||
generated: { | ||
line: currentLine + q, | ||
column: leadingWhitespace ? leadingWhitespace.length : 0 | ||
}, | ||
original: { | ||
line: q + 1, | ||
column: 0 | ||
}, | ||
source: globbedFilePath | ||
}); | ||
} | ||
if (sourceMap.sourcesContent) { | ||
map.setSourceContent(globbedFilePath, resultContent); | ||
} | ||
} | ||
if (sourceMap.sourcesContent) { | ||
map.setSourceContent(globbedFilePath, resultContent); | ||
} | ||
} | ||
// increment/set map line counters | ||
insertedLines += lines; | ||
currentLine += lines; | ||
lastMappedLine = currentLine; | ||
} | ||
// increment/set map line counters | ||
insertedLines += lines; | ||
currentLine += lines; | ||
lastMappedLine = currentLine; | ||
} | ||
if (includedFiles.indexOf(globbedFilePath) == -1) includedFiles.push(globbedFilePath); | ||
if (includedFiles.indexOf(globbedFilePath) == -1) includedFiles.push(globbedFilePath); | ||
// If the last file did not have a line break, and it is not the last file in the matched glob, | ||
// add a line break to the end | ||
if (!resultContent.trim().match(/\n$/) && y != fileMatches.length - 1) { | ||
resultContent += "\n"; | ||
} | ||
// If the last file did not have a line break, and it is not the last file in the matched glob, | ||
// add a line break to the end | ||
if (!resultContent.trim().match(/\n$/) && y != fileMatches.length - 1) { | ||
resultContent += "\n"; | ||
} | ||
if (leadingWhitespace) resultContent = addLeadingWhitespace(leadingWhitespace, resultContent); | ||
if (leadingWhitespace) resultContent = addLeadingWhitespace(leadingWhitespace, resultContent); | ||
replaceContent += resultContent; | ||
} | ||
replaceContent += resultContent; | ||
} | ||
// REPLACE | ||
if (replaceContent.length) { | ||
// sometimes the line matches the leading \n and sometimes it doesn't. wierd. | ||
// in case it does, preserve that leading \n | ||
if (leadingWhitespaceMatch[0][0] === '\n') { | ||
replaceContent = '\n' + replaceContent; | ||
} | ||
// REPLACE | ||
if (replaceContent.length) { | ||
// sometimes the line matches the leading \n and sometimes it doesn't. wierd. | ||
// in case it does, preserve that leading \n | ||
if (leadingWhitespaceMatch[0][0] === '\n') { | ||
replaceContent = '\n' + replaceContent; | ||
} | ||
content = content.replace(matches[i], function () { | ||
return replaceContent | ||
}); | ||
insertedLines--; // adjust because the original line with comment was removed | ||
} | ||
} | ||
content = content.replace(matches[i], function () { | ||
return replaceContent | ||
}); | ||
insertedLines--; // adjust because the original line with comment was removed | ||
} | ||
} | ||
if (sourceMap) { | ||
currentLine = content.match(/^/mg).length + 1; | ||
if (sourceMap) { | ||
currentLine = content.match(/^/mg).length + 1; | ||
mapSelf(currentLine); | ||
} | ||
mapSelf(currentLine); | ||
} | ||
return { | ||
content: content, | ||
map: map ? map.toString() : null | ||
}; | ||
} | ||
return { | ||
content: content, | ||
map: map ? map.toString() : null | ||
}; | ||
} | ||
function unixStylePath(filePath) { | ||
return filePath.replace(/\\/g, '/'); | ||
} | ||
function unixStylePath(filePath) { | ||
return filePath.replace(/\\/g, '/'); | ||
} | ||
function addLeadingWhitespace(whitespace, string) { | ||
return string.split("\n").map(function (line) { | ||
return whitespace + line; | ||
}).join("\n"); | ||
} | ||
function addLeadingWhitespace(whitespace, string) { | ||
return string.split("\n").map(function (line) { | ||
return whitespace + line; | ||
}).join("\n"); | ||
} | ||
function fileNotFoundError(includePath) { | ||
if (hardFail) { | ||
throw new PluginError('gulp-include', 'No files found matching ' + includePath); | ||
} else { | ||
console.warn( | ||
colors.yellow('WARN: ') + | ||
colors.cyan('gulp-include') + | ||
' - no files found matching ' + includePath | ||
); | ||
} | ||
} | ||
function isExplicitRelativePath(filePath) { | ||
return filePath.indexOf('./') === 0; | ||
} | ||
function inExtensions(filePath) { | ||
if (!extensions) return true; | ||
for (var i = 0; i < extensions.length; i++) { | ||
var re = extensions[i] + "$"; | ||
if (filePath.match(re)) return true; | ||
} | ||
return false; | ||
} | ||
function removeRelativePathPrefix(filePath) { | ||
return filePath.replace(/^\.\//, ''); | ||
} | ||
function fileNotFoundError(includePath) { | ||
if (hardFail) { | ||
throw new PluginError('gulp-include', 'No files found matching ' + includePath); | ||
} else { | ||
console.warn( | ||
colors.yellow('WARN: ') + | ||
colors.cyan('gulp-include') + | ||
' - no files found matching ' + includePath | ||
); | ||
} | ||
} | ||
return es.map(include) | ||
function inExtensions(filePath) { | ||
if (!extensions) return true; | ||
for (var i = 0; i < extensions.length; i++) { | ||
var re = extensions[i] + "$"; | ||
if (filePath.match(re)) return true; | ||
} | ||
return false; | ||
} | ||
return es.map(include) | ||
}; |
{ | ||
"name": "gulp-include", | ||
"version": "2.4.0", | ||
"description": "Makes inclusion of files a breeze. Enables functionality similar to that of snockets / sprockets or other file insertion compilation tools.", | ||
"homepage": "http://github.com/wiledal/gulp-include", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/wiledal/gulp-include.git" | ||
}, | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"keywords": [ | ||
"gulpplugin" | ||
], | ||
"author": { | ||
"name": "Hugo Wiledal" | ||
}, | ||
"license": "MIT", | ||
"devDependencies": { | ||
"gulp": "^4.0.0", | ||
"gulp-sourcemaps": "^2.6.5", | ||
"mocha": "^6.0.2", | ||
"should": "^13.2.3", | ||
"stream-assert": "^2.0.3" | ||
}, | ||
"dependencies": { | ||
"ansi-colors": "^3.2.4", | ||
"event-stream": "^4.0.1", | ||
"glob": "^7.1.3", | ||
"plugin-error": "^1.0.1", | ||
"source-map": "^0.7.3", | ||
"strip-bom": "^2.0.0", | ||
"vinyl": "^2.2.0", | ||
"vinyl-sourcemaps-apply": "^0.2.1" | ||
} | ||
"name": "gulp-include", | ||
"version": "2.4.1", | ||
"description": "Makes inclusion of files a breeze. Enables functionality similar to that of snockets / sprockets or other file insertion compilation tools.", | ||
"homepage": "http://github.com/wiledal/gulp-include", | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/wiledal/gulp-include.git" | ||
}, | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha" | ||
}, | ||
"keywords": [ | ||
"gulpplugin" | ||
], | ||
"author": { | ||
"name": "Hugo Wiledal" | ||
}, | ||
"license": "MIT", | ||
"devDependencies": { | ||
"gulp": "^4.0.0", | ||
"gulp-sourcemaps": "^2.6.5", | ||
"mocha": "^6.1.1", | ||
"should": "^13.2.3", | ||
"stream-assert": "^2.0.3" | ||
}, | ||
"dependencies": { | ||
"ansi-colors": "^3.2.4", | ||
"event-stream": "^4.0.1", | ||
"glob": "^7.1.3", | ||
"plugin-error": "^1.0.1", | ||
"source-map": "^0.7.3", | ||
"strip-bom": "^2.0.0", | ||
"vinyl": "^2.2.0", | ||
"vinyl-sourcemaps-apply": "^0.2.1" | ||
} | ||
} |
117
README.md
@@ -1,7 +0,22 @@ | ||
#gulp-include [![NPM version][npm-image]][npm-url] ![Travis build][travis-image] | ||
>Makes inclusion of files a breeze. | ||
Enables functionality similar to that of snockets / sprockets or other file insertion compilation tools. | ||
# gulp-include [![NPM version][npm-image]][npm-url] ![Travis build][travis-image] | ||
> Made for gulp 3 | ||
<table> | ||
<tr> | ||
<td>Package</td><td>gulp-include</td> | ||
</tr> | ||
<tr> | ||
<td>Description</td> | ||
<td>Makes inclusion of files a breeze. Enables functionality similar to that of snockets / sprockets or other file insertion compilation tools.</td> | ||
</tr> | ||
<tr> | ||
<td>Node Version</td> | ||
<td>>= 6.0.0 </td> | ||
</tr> | ||
<tr> | ||
<td>Gulp Version</td> | ||
<td>>= 3.0.0</td> | ||
</table> | ||
> Works with gulp 3 and gulp 4 | ||
## Features | ||
@@ -20,18 +35,45 @@ * Concatenate files with full control | ||
```javascript | ||
var gulp = require("gulp"), | ||
include = require("gulp-include"); | ||
const gulp = require('gulp') | ||
const include = require('gulp-include') | ||
gulp.task("scripts", function() { | ||
console.log("-- gulp is running task 'scripts'"); | ||
gulp.src("src/js/main.js") | ||
exports.scripts = function (done) { | ||
gulp.src('source/js/entry.js') | ||
.pipe(include()) | ||
.on('error', console.log) | ||
.pipe(gulp.dest("dist/js")); | ||
}); | ||
.pipe(gulp.dest('dist/js')) | ||
} | ||
gulp.task("default", ["scripts"]); | ||
``` | ||
## Include directives | ||
`gulp-include` uses directives similar to `sprockets` or `snockets`. A _directive_ is a comment in your files that `gulp-include` recognizes as a command. | ||
Example directives: | ||
```javascript | ||
//=require vendor/jquery.js | ||
//=require vendor/**/*.js | ||
//=include relative/path/to/file.js | ||
//=include ./relative/path/to/file-even-when-includePaths-set.js | ||
``` | ||
```css | ||
/*=include relative/path/to/file.css */ | ||
``` | ||
```coffee | ||
#=include relative/path/to/file.coffee | ||
``` | ||
```html | ||
<!--=include relative/path/to/file.html --> | ||
``` | ||
The contents of the referenced file will replace the file. | ||
### `require` vs. `include` | ||
A file that is included with `require` will only be included if it has not been included before. Files included with `include` will _always_ be included. | ||
For instance, let's say you want to include `jquery.js` only once, and before any of your other scripts in the same folder. | ||
```javascript | ||
//=require vendor/jquery.js | ||
//=require vendor/*.js | ||
``` | ||
Note: This also works recursively. If for instance, for the example above, if another file in the folder `vendor` is also including `jquery.js` with the `require`-directive it will be ignored. | ||
## Options | ||
@@ -48,2 +90,3 @@ - `extensions` (optional) | ||
* If set, `gulp-include` will use these folders as base path when searching for files. | ||
* If set, you can still include files relative to the current file by pre-pending includes with `./`. | ||
@@ -58,51 +101,21 @@ | ||
- `separateInputs` (optional) | ||
* Boolean, `true` by default | ||
* Set this to `false` if you want to process each input file independent, when executing "require" logic. | ||
So, if file required several times inside one file (or inside required by it files), then dublicates will be ignored. | ||
But when another file will begin processing, all information about required files from previuos file will be discarded. | ||
* Boolean, `false` by default | ||
* Set this to `true` to allow each input file to use `require`-directives independently. | ||
* Useful if you are referencing several paths in `gulp.src` and need them to `require` the same files. | ||
#### Example options usage: | ||
```js | ||
gulp.src("src/js/main.js") | ||
gulp.src('src/js/main.js') | ||
.pipe(include({ | ||
extensions: "js", | ||
extensions: 'js', | ||
hardFail: true, | ||
separateInputs: true, | ||
includePaths: [ | ||
__dirname + "/bower_components", | ||
__dirname + "/src/js" | ||
__dirname + '/bower_components', | ||
__dirname + '/src/js' | ||
] | ||
})) | ||
.pipe(gulp.dest("dist/js")); | ||
.pipe(gulp.dest('dist/js')) | ||
``` | ||
## Include directives | ||
`gulp-include` uses directives similar to `sprockets` or `snockets`. A _directive_ is a comment in your files that `gulp-include` recognizes as a command. | ||
Example directives: | ||
```javascript | ||
//=require vendor/jquery.js | ||
//=require vendor/**/*.js | ||
//=include relative/path/to/file.js | ||
``` | ||
```css | ||
/*=include relative/path/to/file.css */ | ||
``` | ||
```coffee | ||
#=include relative/path/to/file.coffee | ||
``` | ||
```html | ||
<!--=include relative/path/to/file.html --> | ||
``` | ||
The contents of the referenced file will replace the file. | ||
### `require` vs. `include` | ||
A file that is included with `require` will only be included if it has not been included before. Files included with `include` will _always_ be included. | ||
For instance, let's say you want to include `jquery.js` only once, and before any of your other scripts in the same folder. | ||
```javascript | ||
//=require vendor/jquery.js | ||
//=require vendor/*.js | ||
``` | ||
Note: This also works recursively. If for instance, for the example above, if another file in the folder `vendor` is also including `jquery.js` with the `require`-directive it will be ignored. | ||
## Changelog | ||
@@ -109,0 +122,0 @@ For release notes see `CHANGELOG.md`. |
467
test/main.js
var should = require("should"), | ||
include = require("../index"), | ||
fs = require("fs"), | ||
vm = require("vm"), | ||
Vinyl = require('vinyl'), | ||
assert = require('stream-assert'), | ||
gulp = require('gulp'), | ||
sourcemaps = require('gulp-sourcemaps'), | ||
path = require("path"); | ||
include = require("../index"), | ||
fs = require("fs"), | ||
vm = require("vm"), | ||
Vinyl = require('vinyl'), | ||
assert = require('stream-assert'), | ||
gulp = require('gulp'), | ||
sourcemaps = require('gulp-sourcemaps'), | ||
path = require("path"); | ||
@@ -14,222 +14,295 @@ | ||
describe("gulp-include", function () { | ||
describe("File including", function () { | ||
it("should replace special comments with file contents", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/basic-include.js", | ||
contents: fs.readFileSync("test/fixtures/js/basic-include.js") | ||
}); | ||
describe("File including", function () { | ||
it("should replace special comments with file contents", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/basic-include.js", | ||
contents: fs.readFileSync("test/fixtures/js/basic-include.js") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/basic-include.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/basic-include.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
it("should keep whitespace when including", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/whitespace.js", | ||
contents: fs.readFileSync("test/fixtures/js/whitespace.js") | ||
}); | ||
it("should keep whitespace when including", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/whitespace.js", | ||
contents: fs.readFileSync("test/fixtures/js/whitespace.js") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/whitespace.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/whitespace.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
it("should include complex folder trees", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-trees.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-trees.js") | ||
}); | ||
it("should include complex folder trees", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-trees.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-trees.js") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/include-trees.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
}) | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/include-trees.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
}) | ||
it("should not REQUIRE a file twice", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/big-dummy-project-file.js", | ||
contents: fs.readFileSync("test/fixtures/js/big-dummy-project-file.js") | ||
}); | ||
it("should not REQUIRE a file twice", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/big-dummy-project-file.js", | ||
contents: fs.readFileSync("test/fixtures/js/big-dummy-project-file.js") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/big-dummy-project-file.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/big-dummy-project-file.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
it("should pull files recursively", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/recursive.js", | ||
contents: fs.readFileSync("test/fixtures/js/recursive.js") | ||
}); | ||
it("should pull files recursively", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/recursive.js", | ||
contents: fs.readFileSync("test/fixtures/js/recursive.js") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/recursive.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/recursive.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
it("should only include files with the set extensions, if provided", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/options-extensions.js", | ||
contents: fs.readFileSync("test/fixtures/js/options-extensions.js") | ||
}); | ||
it("should only include files with the set extensions, if provided", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/options-extensions.js", | ||
contents: fs.readFileSync("test/fixtures/js/options-extensions.js") | ||
}); | ||
testInclude = include({ | ||
extensions: ".txt" | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include({ | ||
extensions: ".txt" | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/options-extensions.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/options-extensions.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}); | ||
it("should work with html-comments", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/html/basic-include.html", | ||
contents: fs.readFileSync("test/fixtures/html/basic-include.html") | ||
}); | ||
it("should work with html-comments", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/html/basic-include.html", | ||
contents: fs.readFileSync("test/fixtures/html/basic-include.html") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/html/basic-include-output.html"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/html/basic-include-output.html"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it('should support source maps', function (done) { | ||
gulp.src('test/fixtures/js/basic-include.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(include()) | ||
.pipe(assert.length(1)) | ||
.pipe(assert.first(function (d) { | ||
d.sourceMap.sources.should.have.length(3); | ||
d.sourceMap.file.should.eql('basic-include.js'); | ||
d.sourceMap.sources.should.eql(['basic-include.js', 'deep_path/b.js', 'deep_path/deeper_path/c.js']) | ||
})) | ||
.pipe(assert.end(done)); | ||
}); | ||
it('should support source maps', function (done) { | ||
gulp.src('test/fixtures/js/basic-include.js') | ||
.pipe(sourcemaps.init()) | ||
.pipe(include()) | ||
.pipe(assert.length(1)) | ||
.pipe(assert.first(function (d) { | ||
d.sourceMap.sources.should.have.length(3); | ||
d.sourceMap.file.should.eql('basic-include.js'); | ||
d.sourceMap.sources.should.eql(['basic-include.js', 'deep_path/b.js', 'deep_path/deeper_path/c.js']) | ||
})) | ||
.pipe(assert.end(done)); | ||
}); | ||
it('should strip unicode byte order marks from included files', function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/html/basic-include-with-unicode-BOM.html", | ||
contents: fs.readFileSync("test/fixtures/html/basic-include-with-unicode-BOM.html") | ||
}); | ||
it('should strip unicode byte order marks from included files', function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/html/basic-include-with-unicode-BOM.html", | ||
contents: fs.readFileSync("test/fixtures/html/basic-include-with-unicode-BOM.html") | ||
}); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include(); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/html/basic-include-output-with-unicode-BOM.html"), "utf8")) | ||
done(); | ||
}); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/html/basic-include-output-with-unicode-BOM.html"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
testInclude.write(file); | ||
}) | ||
it("should include from set includePaths", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-path.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-path.js") | ||
}); | ||
it("should include from set includePaths", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-path.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-path.js") | ||
}); | ||
testInclude = include({ | ||
includePaths: [ | ||
__dirname + "/fixtures/js/include-path", | ||
__dirname + "/fixtures/js/include-path2", | ||
__dirname + "/fixtures/js/include-path2/deeper2", | ||
] | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include({ | ||
includePaths: [ | ||
__dirname + "/fixtures/js/include-path", | ||
__dirname + "/fixtures/js/include-path2", | ||
__dirname + "/fixtures/js/include-path2/deeper2", | ||
] | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/include-path.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/include-path.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it("should include from explicit relative path when includePaths set", function(done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-path-relative.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-path-relative.js") | ||
}); | ||
it("should throw an error if no match is found with hardFail: true", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-fail.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-fail.js") | ||
}); | ||
testInclude = include({ | ||
includePaths: [ | ||
__dirname + "/fixtures/js/include-path", | ||
] | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
testInclude = include({ | ||
hardFail: true | ||
}); | ||
testInclude.on("error", function (err) { | ||
if (err) done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/include-path-relative.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it("should not throw an error if no match is found with hardFail: false", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-fail.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-fail.js") | ||
}); | ||
it("should include relative paths recursively when includePaths does not include recursively-included paths", function(done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/recursive-relative.js", | ||
contents: fs.readFileSync("test/fixtures/js/recursive-relative.js") | ||
}); | ||
testInclude = include({ | ||
hardFail: false | ||
}); | ||
testInclude.on("error", function (err) { | ||
done(err); | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
}) | ||
testInclude = include({ | ||
includePaths: [ | ||
__dirname + "/fixtures/js/include-path", | ||
__dirname + "/fixtures/js/recursive", | ||
] | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/recursive-relative.js"), "utf8")) | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it("should throw an error if no match is found with hardFail: true", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-fail.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-fail.js") | ||
}); | ||
testInclude = include({ | ||
hardFail: true | ||
}); | ||
testInclude.on("error", function (err) { | ||
if (err) done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it("should not throw an error if no match is found with hardFail: false", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/include-fail.js", | ||
contents: fs.readFileSync("test/fixtures/js/include-fail.js") | ||
}); | ||
testInclude = include({ | ||
hardFail: false | ||
}); | ||
testInclude.on("error", function (err) { | ||
done(err); | ||
}); | ||
testInclude.on("data", function (newFile) { | ||
done(); | ||
}); | ||
testInclude.write(file); | ||
}) | ||
it("should allow `separateInputs: true` to `require` the same file, if in different streams", function (done) { | ||
var file = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/separate-inputs/separate-inputs.js", | ||
contents: fs.readFileSync("test/fixtures/js/separate-inputs/separate-inputs.js") | ||
}); | ||
var file2 = new Vinyl({ | ||
base: "test/fixtures/", | ||
path: "test/fixtures/js/separate-inputs/separate-inputs.js", | ||
contents: fs.readFileSync("test/fixtures/js/separate-inputs/separate-inputs.js") | ||
}); | ||
testInclude = include({ | ||
separateInputs: true | ||
}); | ||
var index = 0 | ||
testInclude.on("data", function (newFile) { | ||
index++ | ||
should.exist(newFile); | ||
should.exist(newFile.contents); | ||
String(newFile.contents).should.equal(String(fs.readFileSync("test/expected/js/separate-inputs.js"), "utf8")) | ||
if (index==2) done(); | ||
}); | ||
testInclude.write(file); | ||
testInclude.write(file2); | ||
}) | ||
}) |
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
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
165807
50
660
149