Skip to content

Keep vendors in separate folders #385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 3, 2018
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
126 changes: 126 additions & 0 deletions build/vendors-sass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env node

'use strict'

const autoprefixer = require('autoprefixer');
const chalk = require('chalk')
const fs = require('fs')
const glob = require('glob')
const mkdirp = require('mkdirp')
const path = require('path')
const postcss = require('postcss');
const sass = require('node-sass')
const sh = require('shelljs')

const basename = path.basename
const dirname = path.dirname
const resolve = path.resolve
const normalize = path.normalize
const join = path.join
const relative = path.relative
const extension = path.extname

const vendors = () => {
const cwd = 'src/scss/vendors/'
const pattern = '**/*.scss'
const ignore = '**/_*.scss'
const options = {
cwd: cwd,
ignore: ignore
}
const filenames = new glob.sync(pattern, options)
return filenames.map((filename) => {
const obj = {}
obj['dir'] = filename.split('/')[0]
obj['path'] = resolve(cwd, filename)
return obj
})
}

const compileSass = (options = {}) => {
// set default options
options = Object.assign({
style: 'expanded'
}, options);

// render the result
let compiled
try {
compiled = sass.renderSync({
file: options.src,
outFile: options.dest,
outputStyle: options.style,
precision: 6,
sourceMap: true,
sourceMapContents: true
})
} catch(e) {
// catch error, the process crashed
const error = `
file: ${e.file},
line: ${e.line},
column: ${e.column},
message: ${e.message},
formatted: ${e.formatted}
`
console.log(chalk.red(error))
return
}

if (compiled && compiled.css){
console.log(chalk.green('Rendering Complete, saving .css file...'))
console.log(chalk.green(`Wrote CSS to ${options.dest}`))
console.log(chalk.green(`Wrote Source Map to ${options.map}`))
console.log(`\n`)

// add prefixes
const prefixed = postcss([ autoprefixer ]).process(compiled.css, {
from: options.src,
to: options.dest
})
prefixed.then((result) => {
result.warnings().forEach((warning) => {
console.warn(warning.toString())
})
// write the result to file
mkdirp(dirname(options.dest), (error) => {
if (error) return cb(error)
// create .css file
fs.writeFile(options.dest,result.css, (error) => {
if (error) return cb(error)
})
// create .css.map file
fs.writeFile(options.dest,compiled.map, (error) => {
if (error) return cb(error)
})
console.log(' ' + options.dest + ' built.');
})
})
}
}

const compile = (vendors) => {
vendors.forEach((vendor) => {
const dest = resolve(__dirname, '..', 'src/vendors', vendor.dir, 'css', path.parse(vendor.path).name)
// Expanded
compileSass({
src : vendor.path,
dest: dest + '.css',
map: dest + '.css.map'
});

// Minified
compileSass({
src : vendor.path,
dest: dest + '.min.css',
map: dest + '.min.css.map',
style: 'compressed'
});
})
}

const main = () => {
compile(vendors())
}

main()
156 changes: 96 additions & 60 deletions build/vendors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,141 @@

'use strict'

const fs = require('fs');
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs')
const path = require('path')
const mkdirp = require('mkdirp')
const sh = require('shelljs')

const basename = path.basename;
const dirname = path.dirname;
const resolve = path.resolve;
const normalize = path.normalize;
const join = path.join;
const relative = path.relative;
const extension = path.extname;
const basename = path.basename
const dirname = path.dirname
const resolve = path.resolve
const normalize = path.normalize
const join = path.join
const relative = path.relative
const extension = path.extname

const src = 'src/';
const dest = 'dist/';
const src = 'src/'
const dest = 'dist/'
const base = path.resolve(__dirname, '..')

const walkSync = (dir, filelist = []) => {
fs.readdirSync(dir).forEach(file => {
filelist = fs.statSync(path.join(dir, file)).isDirectory()
? walkSync(path.join(dir, file), filelist)
: filelist.concat(path.join(dir, file));
});
return filelist;
? walkSync(path.join(dir, file), filelist)
: filelist.concat(path.join(dir, file))
})
return filelist
}

const vendorName = (path) => {
const nodeModules = Boolean(path.split('/')[0] === 'node_modules')
const subDir = Boolean(path.indexOf('@') >= 0)
let vendor
if (nodeModules) {
if (subDir) {
vendor = `${path.split('/')[1]}/${path.split('/')[2]}`
} else {
vendor = `${path.split('/')[1]}`
}
}
return vendor
}

function removeDuplicates( arr, prop ) {
let obj = {};
return Object.keys(arr.reduce((prev, next) => {
if(!obj[next[prop]]) obj[next[prop]] = next;
return obj;
}, obj)).map((i) => obj[i]);
}

const findVendors = () => {
const vendors = { css: [], js: [], other: [] };
const vendors = []
// const assets = []
// const vendors = { css: [], js: [], other: [] }
const filenames = walkSync(src)

filenames.forEach((filename) => {
if (extension(filename) === '.html') {
const files = fs.readFileSync(filename, 'ascii').toString().split('\n');
const files = fs.readFileSync(filename, 'ascii').toString().split('\n')

// go through the list of logFileLines
// go through the list of code lines
files.forEach((file) => {

// if the current line matches SAVE, it will be stored in the variable lines
if(file.match(/node_modules/)) {

const js = file.match(/node_modules.*.js/)
if (js !== null) {
// vendors.js.indexOf(resolve(js[0])) === -1 ? vendors.js.push({'html':js[0],'absolute':resolve(js[0]) }) : '';
vendors.js.map((item) => { return item.html }).indexOf(js[0]) === -1 ? vendors.js.push({'html':js[0],'absolute':resolve(js[0]) }) : '';
}
const css = file.match(/node_modules.*.css/)
if (css !== null) {
if (vendors.css.map((item) => { return item.html }).indexOf(css[0]) === -1) {
// vendors.css.push(resolve(css[0]))
vendors.css.push({'html':css[0],'absolute':resolve(css[0]) })

const assets = fs.readFileSync(css[0], 'ascii').toString().match(/url\(.*?\)/ig);
assets.forEach(function(asset) {
const assetPath = asset.replace(/\?.*/g, '').replace('url(','').replace(/\'/g, '').replace(')','');
vendors.other.push({'absolute' : resolve(dirname(css[0]), assetPath), 'relative' : assetPath })
})
// if the current line matches `/(?:href|src)="(node_modules.*.[css|js])"/`, it will be stored in the variable lines
const nodeModules = file.match(/(?:href|src)="(node_modules.*.[css|js])"/)
if (nodeModules) {
let vendor = []
const src = nodeModules[1]
const name = vendorName(src)
let type
let absolute

vendor['name'] = name
vendor['filetype'] = extension(src).replace('.', '')
vendor['src'] = src
vendor['absolute'] = resolve(src)

if (vendors.findIndex(vendor => vendor.absolute === resolve(src)) === -1) {
vendors.push(vendor)

// Check it CSS file has assets
if (extension(src) === '.css') {
const assets = fs.readFileSync(resolve(src), 'ascii').toString().match(/(?:url)\((.*?)\)/ig)
if (assets) {
assets.forEach((asset) => {
const assetPath = asset.match(/(?:url)\((.*?)\)/)[1]
let subVendor = []
if (assetPath !== undefined) {
// console.log(assetPath)
const path = assetPath.replace(/\?.*/, '').replace(/\'|\"/, '')
subVendor['name'] = name
subVendor['filetype'] = 'other'
subVendor['src'] = normalize(`css/${path}`)
subVendor['absolute'] = resolve(dirname(src), path)

vendors.push(subVendor)
}
})
}
}
}
}
})
}
})
return vendors;
return vendors
}

const copyFiles = (files, dest) => {
files.forEach((file) => {
mkdirp.sync(resolve(dest));
fs.createReadStream(file).pipe(fs.createWriteStream(resolve(dest, basename(file))));
})
}
let dir
file.filetype !== 'other' ? dir = resolve(dest, file.name, file.filetype) : dir = resolve(dest, file.name, dirname(file.src))
mkdirp.sync(dir)
fs.createReadStream(file.absolute).pipe(fs.createWriteStream(resolve(dir, basename(file.src))))

const copyOtherFiles = (files, dest) => {
files.forEach((file) => {
mkdirp.sync(resolve(dest + dirname(file.relative)));
fs.createReadStream(file.absolute).pipe(fs.createWriteStream(resolve(dest, file.relative)));
if (fs.existsSync(`${file.absolute}.map`)) {
fs.createReadStream(`${file.absolute}.map`).pipe(fs.createWriteStream(resolve(dir, `${basename(file.src)}.map`)))
}
})
}

const replaceRecursively = (filename, original) => {
const replacement = 'vendors/' + extension(original).replace('.','') + '/' + basename(original);
const replaceRecursively = (filename, vendor) => {
const original = vendor.src
const replacement = `vendors/${vendor.name}/${vendor.filetype}/${basename(vendor.src)}`
sh.sed('-i', original, replacement, filename)
}

const main = () => {

const vendors = findVendors()

copyFiles(vendors.css.map((item) => { return item.absolute }), './dist/vendors/css/');
copyFiles(vendors.js.map((item) => { return item.absolute }), './dist/vendors/js/');
copyOtherFiles(vendors.other, './dist/vendors/css/');

copyFiles(vendors.map((file) => { return file }), './dist/vendors/')
const filenames = walkSync(dest)
filenames.forEach((filename) => {
if (extension(filename) === '.html') {
vendors.css.map((item) => {
replaceRecursively(resolve(filename), item.html)
})
vendors.js.map((item) => {
replaceRecursively(resolve(filename), item.html)
vendors.map((vendor) => {
if (vendor.filetype !== 'other') {
replaceRecursively(resolve(filename), vendor)
}
})
}
})
Expand Down
Loading