Skip to content

Commit 657c554

Browse files
authored
Merge pull request #385 from coreui/refactor-build-vendors
Keep vendors in separate folders
2 parents 04bd126 + cca4882 commit 657c554

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+593
-520
lines changed

build/vendors-sass.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env node
2+
3+
'use strict'
4+
5+
const autoprefixer = require('autoprefixer');
6+
const chalk = require('chalk')
7+
const fs = require('fs')
8+
const glob = require('glob')
9+
const mkdirp = require('mkdirp')
10+
const path = require('path')
11+
const postcss = require('postcss');
12+
const sass = require('node-sass')
13+
const sh = require('shelljs')
14+
15+
const basename = path.basename
16+
const dirname = path.dirname
17+
const resolve = path.resolve
18+
const normalize = path.normalize
19+
const join = path.join
20+
const relative = path.relative
21+
const extension = path.extname
22+
23+
const vendors = () => {
24+
const cwd = 'src/scss/vendors/'
25+
const pattern = '**/*.scss'
26+
const ignore = '**/_*.scss'
27+
const options = {
28+
cwd: cwd,
29+
ignore: ignore
30+
}
31+
const filenames = new glob.sync(pattern, options)
32+
return filenames.map((filename) => {
33+
const obj = {}
34+
obj['dir'] = filename.split('/')[0]
35+
obj['path'] = resolve(cwd, filename)
36+
return obj
37+
})
38+
}
39+
40+
const compileSass = (options = {}) => {
41+
// set default options
42+
options = Object.assign({
43+
style: 'expanded'
44+
}, options);
45+
46+
// render the result
47+
let compiled
48+
try {
49+
compiled = sass.renderSync({
50+
file: options.src,
51+
outFile: options.dest,
52+
outputStyle: options.style,
53+
precision: 6,
54+
sourceMap: true,
55+
sourceMapContents: true
56+
})
57+
} catch(e) {
58+
// catch error, the process crashed
59+
const error = `
60+
file: ${e.file},
61+
line: ${e.line},
62+
column: ${e.column},
63+
message: ${e.message},
64+
formatted: ${e.formatted}
65+
`
66+
console.log(chalk.red(error))
67+
return
68+
}
69+
70+
if (compiled && compiled.css){
71+
console.log(chalk.green('Rendering Complete, saving .css file...'))
72+
console.log(chalk.green(`Wrote CSS to ${options.dest}`))
73+
console.log(chalk.green(`Wrote Source Map to ${options.map}`))
74+
console.log(`\n`)
75+
76+
// add prefixes
77+
const prefixed = postcss([ autoprefixer ]).process(compiled.css, {
78+
from: options.src,
79+
to: options.dest
80+
})
81+
prefixed.then((result) => {
82+
result.warnings().forEach((warning) => {
83+
console.warn(warning.toString())
84+
})
85+
// write the result to file
86+
mkdirp(dirname(options.dest), (error) => {
87+
if (error) return cb(error)
88+
// create .css file
89+
fs.writeFile(options.dest,result.css, (error) => {
90+
if (error) return cb(error)
91+
})
92+
// create .css.map file
93+
fs.writeFile(options.dest,compiled.map, (error) => {
94+
if (error) return cb(error)
95+
})
96+
console.log(' ' + options.dest + ' built.');
97+
})
98+
})
99+
}
100+
}
101+
102+
const compile = (vendors) => {
103+
vendors.forEach((vendor) => {
104+
const dest = resolve(__dirname, '..', 'src/vendors', vendor.dir, 'css', path.parse(vendor.path).name)
105+
// Expanded
106+
compileSass({
107+
src : vendor.path,
108+
dest: dest + '.css',
109+
map: dest + '.css.map'
110+
});
111+
112+
// Minified
113+
compileSass({
114+
src : vendor.path,
115+
dest: dest + '.min.css',
116+
map: dest + '.min.css.map',
117+
style: 'compressed'
118+
});
119+
})
120+
}
121+
122+
const main = () => {
123+
compile(vendors())
124+
}
125+
126+
main()

build/vendors.js

Lines changed: 96 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,105 +2,141 @@
22

33
'use strict'
44

5-
const fs = require('fs');
6-
const path = require('path');
7-
const mkdirp = require('mkdirp');
5+
const fs = require('fs')
6+
const path = require('path')
7+
const mkdirp = require('mkdirp')
88
const sh = require('shelljs')
99

10-
const basename = path.basename;
11-
const dirname = path.dirname;
12-
const resolve = path.resolve;
13-
const normalize = path.normalize;
14-
const join = path.join;
15-
const relative = path.relative;
16-
const extension = path.extname;
10+
const basename = path.basename
11+
const dirname = path.dirname
12+
const resolve = path.resolve
13+
const normalize = path.normalize
14+
const join = path.join
15+
const relative = path.relative
16+
const extension = path.extname
1717

18-
const src = 'src/';
19-
const dest = 'dist/';
18+
const src = 'src/'
19+
const dest = 'dist/'
20+
const base = path.resolve(__dirname, '..')
2021

2122
const walkSync = (dir, filelist = []) => {
2223
fs.readdirSync(dir).forEach(file => {
2324
filelist = fs.statSync(path.join(dir, file)).isDirectory()
24-
? walkSync(path.join(dir, file), filelist)
25-
: filelist.concat(path.join(dir, file));
26-
});
27-
return filelist;
25+
? walkSync(path.join(dir, file), filelist)
26+
: filelist.concat(path.join(dir, file))
27+
})
28+
return filelist
29+
}
30+
31+
const vendorName = (path) => {
32+
const nodeModules = Boolean(path.split('/')[0] === 'node_modules')
33+
const subDir = Boolean(path.indexOf('@') >= 0)
34+
let vendor
35+
if (nodeModules) {
36+
if (subDir) {
37+
vendor = `${path.split('/')[1]}/${path.split('/')[2]}`
38+
} else {
39+
vendor = `${path.split('/')[1]}`
40+
}
41+
}
42+
return vendor
43+
}
44+
45+
function removeDuplicates( arr, prop ) {
46+
let obj = {};
47+
return Object.keys(arr.reduce((prev, next) => {
48+
if(!obj[next[prop]]) obj[next[prop]] = next;
49+
return obj;
50+
}, obj)).map((i) => obj[i]);
2851
}
2952

3053
const findVendors = () => {
31-
const vendors = { css: [], js: [], other: [] };
54+
const vendors = []
55+
// const assets = []
56+
// const vendors = { css: [], js: [], other: [] }
3257
const filenames = walkSync(src)
3358

3459
filenames.forEach((filename) => {
3560
if (extension(filename) === '.html') {
36-
const files = fs.readFileSync(filename, 'ascii').toString().split('\n');
61+
const files = fs.readFileSync(filename, 'ascii').toString().split('\n')
3762

38-
// go through the list of logFileLines
63+
// go through the list of code lines
3964
files.forEach((file) => {
4065

41-
// if the current line matches SAVE, it will be stored in the variable lines
42-
if(file.match(/node_modules/)) {
43-
44-
const js = file.match(/node_modules.*.js/)
45-
if (js !== null) {
46-
// vendors.js.indexOf(resolve(js[0])) === -1 ? vendors.js.push({'html':js[0],'absolute':resolve(js[0]) }) : '';
47-
vendors.js.map((item) => { return item.html }).indexOf(js[0]) === -1 ? vendors.js.push({'html':js[0],'absolute':resolve(js[0]) }) : '';
48-
}
49-
const css = file.match(/node_modules.*.css/)
50-
if (css !== null) {
51-
if (vendors.css.map((item) => { return item.html }).indexOf(css[0]) === -1) {
52-
// vendors.css.push(resolve(css[0]))
53-
vendors.css.push({'html':css[0],'absolute':resolve(css[0]) })
54-
55-
const assets = fs.readFileSync(css[0], 'ascii').toString().match(/url\(.*?\)/ig);
56-
assets.forEach(function(asset) {
57-
const assetPath = asset.replace(/\?.*/g, '').replace('url(','').replace(/\'/g, '').replace(')','');
58-
vendors.other.push({'absolute' : resolve(dirname(css[0]), assetPath), 'relative' : assetPath })
59-
})
66+
// if the current line matches `/(?:href|src)="(node_modules.*.[css|js])"/`, it will be stored in the variable lines
67+
const nodeModules = file.match(/(?:href|src)="(node_modules.*.[css|js])"/)
68+
if (nodeModules) {
69+
let vendor = []
70+
const src = nodeModules[1]
71+
const name = vendorName(src)
72+
let type
73+
let absolute
74+
75+
vendor['name'] = name
76+
vendor['filetype'] = extension(src).replace('.', '')
77+
vendor['src'] = src
78+
vendor['absolute'] = resolve(src)
79+
80+
if (vendors.findIndex(vendor => vendor.absolute === resolve(src)) === -1) {
81+
vendors.push(vendor)
82+
83+
// Check it CSS file has assets
84+
if (extension(src) === '.css') {
85+
const assets = fs.readFileSync(resolve(src), 'ascii').toString().match(/(?:url)\((.*?)\)/ig)
86+
if (assets) {
87+
assets.forEach((asset) => {
88+
const assetPath = asset.match(/(?:url)\((.*?)\)/)[1]
89+
let subVendor = []
90+
if (assetPath !== undefined) {
91+
// console.log(assetPath)
92+
const path = assetPath.replace(/\?.*/, '').replace(/\'|\"/, '')
93+
subVendor['name'] = name
94+
subVendor['filetype'] = 'other'
95+
subVendor['src'] = normalize(`css/${path}`)
96+
subVendor['absolute'] = resolve(dirname(src), path)
97+
98+
vendors.push(subVendor)
99+
}
100+
})
101+
}
60102
}
61103
}
62104
}
63105
})
64106
}
65107
})
66-
return vendors;
108+
return vendors
67109
}
68110

69111
const copyFiles = (files, dest) => {
70112
files.forEach((file) => {
71-
mkdirp.sync(resolve(dest));
72-
fs.createReadStream(file).pipe(fs.createWriteStream(resolve(dest, basename(file))));
73-
})
74-
}
113+
let dir
114+
file.filetype !== 'other' ? dir = resolve(dest, file.name, file.filetype) : dir = resolve(dest, file.name, dirname(file.src))
115+
mkdirp.sync(dir)
116+
fs.createReadStream(file.absolute).pipe(fs.createWriteStream(resolve(dir, basename(file.src))))
75117

76-
const copyOtherFiles = (files, dest) => {
77-
files.forEach((file) => {
78-
mkdirp.sync(resolve(dest + dirname(file.relative)));
79-
fs.createReadStream(file.absolute).pipe(fs.createWriteStream(resolve(dest, file.relative)));
118+
if (fs.existsSync(`${file.absolute}.map`)) {
119+
fs.createReadStream(`${file.absolute}.map`).pipe(fs.createWriteStream(resolve(dir, `${basename(file.src)}.map`)))
120+
}
80121
})
81122
}
82123

83-
const replaceRecursively = (filename, original) => {
84-
const replacement = 'vendors/' + extension(original).replace('.','') + '/' + basename(original);
124+
const replaceRecursively = (filename, vendor) => {
125+
const original = vendor.src
126+
const replacement = `vendors/${vendor.name}/${vendor.filetype}/${basename(vendor.src)}`
85127
sh.sed('-i', original, replacement, filename)
86128
}
87129

88130
const main = () => {
89-
90131
const vendors = findVendors()
91-
92-
copyFiles(vendors.css.map((item) => { return item.absolute }), './dist/vendors/css/');
93-
copyFiles(vendors.js.map((item) => { return item.absolute }), './dist/vendors/js/');
94-
copyOtherFiles(vendors.other, './dist/vendors/css/');
95-
132+
copyFiles(vendors.map((file) => { return file }), './dist/vendors/')
96133
const filenames = walkSync(dest)
97134
filenames.forEach((filename) => {
98135
if (extension(filename) === '.html') {
99-
vendors.css.map((item) => {
100-
replaceRecursively(resolve(filename), item.html)
101-
})
102-
vendors.js.map((item) => {
103-
replaceRecursively(resolve(filename), item.html)
136+
vendors.map((vendor) => {
137+
if (vendor.filetype !== 'other') {
138+
replaceRecursively(resolve(filename), vendor)
139+
}
104140
})
105141
}
106142
})

0 commit comments

Comments
 (0)