Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/plugins/css_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = class CSSWebpackPlugin {
compiler.plugin('make', (compilation, done) => {
cssFiles = compiler.options.spike.files.css
this.util.addFilesAsWebpackEntries(compilation, cssFiles)
.done(() => done())
.done(() => done(), done)
})

// grab the sources and dependencies and export them into the right files
Expand All @@ -48,7 +48,7 @@ module.exports = class CSSWebpackPlugin {
let src = _eval(srcFn, f) // eslint-disable-line
src = src[0][1] // this part is questionable, but it is what it is
const outputPath = this.util.getOutputPath(f)
const newPath = outputPath.replace(/\.[^/.]+$/, '.css')
const newPath = outputPath.relative.replace(/\.[^/.]+$/, '.css')
compilation.assets[newPath] = {
source: () => { return src },
size: () => { return src.length }
Expand Down
147 changes: 80 additions & 67 deletions lib/plugins/fs_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
const path = require('path')
const glob = require('glob')
const micromatch = require('micromatch')
const File = require('filewrap')

/**
* @class FsWebpackPlugin
Expand All @@ -23,81 +24,93 @@ module.exports = class FsWebpackPlugin {
this.util = util
}

/**
* Main webpack plugin entry point
*/
apply (compiler) {
compiler.plugin('run', run.bind(this, compiler))
compiler.plugin('watch-run', run.bind(this, compiler))
this.util.runAll(compiler, this.run.bind(this, compiler))
}
}

function run (compiler, compilation, done) {
compiler.options.spike.files = getFilesFromGlob(this.util)
compiler.options.module.loaders.map((l) => {
if (!l._core) { return }
const files = compiler.options.spike.files[l._core]
l.test = pathToRegex(files)
})
done()
}
/**
* Function that is executed at the beginning of the compile process
*/
run (compiler, compilation, done) {
compiler.options.spike.files = this.getFilesFromGlob()
compiler.options.module.loaders.map((l) => {
if (!l._core) { return }
const files = compiler.options.spike.files[l._core]
l.test = pathToRegex(files)
})
done()
}

function pathToRegex (paths) {
if (!paths.length) { return new RegExp('^.^') }
return new RegExp(paths.map((p, i) => {
return p.replace(/\//g, '\\/')
}).join('|'))
}
/**
* Given the config options, pulls all files from the fs that match any of the
* provided matchers.
* @return {Array} all matching file paths, absolute
*/
getFilesFromGlob () {
let files = {}
const util = this.util

/**
* Given the config options, pulls all files from the fs that match any of the
* provided matchers.
* @param {Object} util - spikeUtils object
* @param {Object} util.conf - configuration values from webpack + spike
* @param {String} util.conf.context - the root path of your spike project
* @param {String} util.conf.module.loaders - configured webpack loaders
* @param {Object} util.conf.spike - spike specific config values
* @param {Array} util.conf.spike.ignore - a glob pattern of files/dirs to ignore
* @param {Array} util.conf.spike.vendor - an array of glob patterns of files to vendor
* @param {Object} util.conf.spike.matchers - core spike matchers
* @return {Array} all matching file paths, absolute
*/
function getFilesFromGlob (util) {
let files = {}
const matcher = path.join(util.conf.context, '**/**')
files.all = glob.sync(matcher, { ignore: util.conf.spike.ignore, dot: true, nodir: true })

// Grab any file match tests from user-provided loaders
const customLoaderTests = util.conf.module.loaders.reduce((m, l) => {
if (!l._core) m.push(l.test)
return m
}, [])

files.vendored = []
if (util.conf.spike.vendor) {
// push all matched vendored paths into `static` category
const vendorTests = util.conf.spike.vendor.map(micromatch.makeRe)
for (const vendorTest of vendorTests) {
files.all.forEach((f) => {
if (util.getOutputPath(f).match(vendorTest)) { files.vendored.push(f) }
})
}
}
// First, we grab all the files in the project, other than the ignored
// files of course.

const matcher = path.join(util.conf.context, '**/**')
files.all = glob.sync(matcher, { ignore: util.conf.spike.ignore, dot: true, nodir: true })

// There are two special types of files we want to *not* be processed by
// spike's core plugins. Any files that are already being processed by a
// user-added loader, and any files in the `vendored` config. Here, we find
// these two types of files and push them into their own custom categories.

// push all files matched by custom loaders into a `custom` category
files.custom = []
for (const loaderTest of customLoaderTests) {
files.all.forEach((f) => {
if (f.match(loaderTest)) { files.custom.push(f) }
const customLoaderTests = util.conf.module.loaders.reduce((m, l) => {
if (!l._core) m.push(l.test); return m
}, [])

files.custom = files.all.filter((f) => {
return customLoaderTests.find((t) => f.match(t) && f)
})
}

// Core matchers do not match files that are already covered by custom loaders or vendored paths
const excludedFiles = files.custom.concat(files.vendored)
const allWithoutCustomOrVendored = files.all.filter((f) => excludedFiles.indexOf(f) < 0)
for (const key in util.conf.spike.matchers) {
files[key] = micromatch(allWithoutCustomOrVendored, util.conf.spike.matchers[key], { dot: true })
}
files.vendored = files.all.filter((f) => {
const file = new File(util.conf.context, f)
return util.matchGlobs(file.relative, util.conf.spike.vendor)[0]
})

// Now we go through the rest of the eligible files and sort them into
// categories according to which plugin will process them, using the
// `matchers` config, which matches by file extension. This does not
// include any ignored, vendored, or custom loader processed files, as we
// have separared these earlier.

// add vendored files to files.static to be emitted by webpack
if (util.conf.spike.vendor) { files.static = files.vendored.concat(files.static) }
const allWithoutCustomOrVendored = files.all.filter((f) => {
return files.custom.concat(files.vendored).indexOf(f) < 0
})

for (const key in util.conf.spike.matchers) {
files[key] = micromatch(allWithoutCustomOrVendored, util.conf.spike.matchers[key], { dot: true })
}

// Finally, we add vendored files to files.static so that they are written
// by the static plugin, without modification.

if (files.vendored.length) {
files.static = files.static.concat(files.vendored)
}

return files
return files
}
}

/**
* Given an array of paths, convert to a regex that matches for presence of
* any of the given paths in a single path.
* @param {Array} paths - array of absolute paths
* @return {RegExp} regex that matches presence of any of the input paths
*/
function pathToRegex (paths) {
if (!paths.length) { return new RegExp('^.^') }
return new RegExp(paths.map((p, i) => {
return p.replace(/\//g, '\\/')
}).join('|'))
}
8 changes: 4 additions & 4 deletions lib/plugins/jade_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = class JadeWebpackPlugin {
compiler.plugin('make', (compilation, done) => {
jadeFiles = compiler.options.spike.files.jade
this.util.addFilesAsWebpackEntries(compilation, jadeFiles)
.done(() => done())
.done(() => done(), done)
})

// grab the sources and dependencies and export them into the right files
Expand Down Expand Up @@ -64,11 +64,11 @@ module.exports = class JadeWebpackPlugin {

// add HTML asset references as dependencies in webpack
srcs.forEach((src) => {
const p = this.util.resolveRelativeSourcePath(src)
dep.fileDependencies.push(p)
const p = this.util.getSourcePath(src)
dep.fileDependencies.push(p.relative)
})

const outputPath = this.util.getOutputPath(f).replace(/\.jade$/, '.html')
const outputPath = this.util.getOutputPath(f).relative.replace(/\.jade$/, '.html')
compilation.assets[outputPath] = {
source: () => { return src },
size: () => { return src.length }
Expand Down
4 changes: 2 additions & 2 deletions lib/plugins/static_plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = class StaticWebpackPlugin {
compiler.plugin('make', (compilation, done) => {
staticFiles = compiler.options.spike.files.static
this.util.addFilesAsWebpackEntries(compilation, staticFiles)
.done(() => done())
.done(() => done(), done)
})

// grab the sources and dependencies and export them into the right files
Expand All @@ -44,7 +44,7 @@ module.exports = class StaticWebpackPlugin {

const src = dep._src

const outputPath = this.util.getOutputPath(f)
const outputPath = this.util.getOutputPath(f).relative
compilation.assets[outputPath] = {
source: () => { return src },
size: () => { return src.length }
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"browser-sync-webpack-plugin": "^1.0.1",
"cheerio": "^0.20.0",
"css-loader": "^0.23.1",
"filewrap": "^0.1.0",
"glob": "^7.0.3",
"hygienist-middleware": "^0.1.1",
"jade": "^1.11.0",
Expand All @@ -30,7 +31,7 @@
"require-from-string": "^1.2.0",
"rimraf": "^2.5.2",
"source-loader": "^0.1.0",
"spike-util": "0.0.1",
"spike-util": "^0.1.0",
"sprout": "^1.2.0",
"webpack": "^1.13.0",
"when": "^3.7.7"
Expand Down