UNPKG

vc-tools

Version:
525 lines (482 loc) 14.4 kB
'use strict'; const gulp = require('gulp'); const path = require('path'); const through2 = require('through2'); const webpack = require('webpack'); const shelljs = require('shelljs'); const babel = require('gulp-babel'); const fs = require('fs-extra'); const argv = require('minimist')(process.argv.slice(2)); const postcss = require('gulp-postcss'); const chalk = require('chalk'); const ts = require('gulp-typescript'); const merge2 = require('merge2'); const glob = require('glob'); const assign = require('object-assign'); const minify = require('gulp-babel-minify'); const prettier = require('gulp-prettier'); const resolveCwd = require('./resolveCwd'); const getWebpackConfig = require('./getWebpackConfig'); const { runCmd, getNpmArgs } = require('./util'); const getBabelCommonConfig = require('./getBabelCommonConfig'); const tsConfig = require('./getTSCommonConfig')(); const { measureFileSizesBeforeBuild, printFileSizesAfterBuild } = require('./FileSizeReporter'); const replaceLib = require('./replaceLib'); const { printResult } = require('./gulpTasks/util'); const pkg = require(resolveCwd('package.json')); const cwd = process.cwd(); const lessPath = new RegExp(`(["']${pkg.name})/assets/([^.'"]+).less`, 'g'); const tsDefaultReporter = ts.reporter.defaultReporter(); const src = argv.src || 'src'; // ============================== Clean ============================== const cleanTasks = require('./gulpTasks/cleanTasks'); const { cleanCompile } = cleanTasks; cleanTasks(gulp); // ============================== MISC =============================== gulp.task( 'check-deps', gulp.series((done) => { if (argv['check-deps'] !== false) { require('./checkDep')(done); } }) ); function reportError() { console.log(chalk.bgRed('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')); console.log(chalk.bgRed('!! `npm publish` is forbidden for this package. !!')); console.log(chalk.bgRed('!! Use `npm run pub` instead. !!')); console.log(chalk.bgRed('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')); } gulp.task( 'guard', gulp.series((done) => { const npmArgs = getNpmArgs(); if (npmArgs) { for (let arg = npmArgs.shift(); arg; arg = npmArgs.shift()) { if (/^pu(b(l(i(sh?)?)?)?)?$/.test(arg) && npmArgs.indexOf('--with-vc-tools') < 0) { reportError(); done(1); return; } } } done(); }) ); // ============================= Package ============================= gulp.task('css', () => { const less = require('gulp-less'); return gulp .src('assets/*.less') .pipe(less()) .pipe(postcss([require('./getAutoprefixer')()])) .pipe(gulp.dest('assets')); }); function babelifyInternal(js, modules) { function replacer(match, m1, m2) { return `${m1}/assets/${m2}.css`; } const babelConfig = getBabelCommonConfig(modules); if (modules === false) { babelConfig.plugins.push(replaceLib); } let stream = js.pipe(babel(babelConfig)); if (argv.compress) { stream = stream.pipe(minify()); } return stream .pipe( through2.obj(function (file, encoding, next) { const contents = file.contents.toString(encoding).replace(lessPath, replacer); file.contents = Buffer.from(contents); this.push(file); next(); }) ) .pipe(gulp.dest(modules !== false ? 'lib' : 'es')); } gulp.task( 'genPrettierrc', gulp.series((done) => { const dir = resolveCwd('./'); const prettierrc = path.join(__dirname, '../config/.prettierrc'); const prettierrcContent = fs.readFileSync(prettierrc); fs.writeFileSync(path.join(dir, './.prettierrc'), prettierrcContent); done(); }) ); gulp.task( 'prettier', gulp.series(() => { let fileList = (argv._ || []).slice(1); if (!fileList.length) { fileList = [ './src/**/*.{js,jsx}', './tests/**/*.{js,jsx}', './code/**/*.{js,jsx}', './storybook/**/*.{js,jsx}', './examples/**/*.{js,jsx}', ]; } else { console.log(chalk.blue(`Prettier:\n${fileList.join('\n')}`)); } const prettierrc = path.join(__dirname, '../config/.prettierrc'); const prettierrcContent = fs.readFileSync(prettierrc, 'utf8'); return gulp .src(fileList) .pipe( prettier(JSON.parse(prettierrcContent), { reporter: 'error', }) ) .pipe(gulp.dest((file) => file.base)); }) ); gulp.task( 'genEslint', gulp.series((done) => { const dir = resolveCwd('./'); const eslintConfig = path.join(__dirname, '../config/eslintrc.js'); const eslintContent = fs.readFileSync(eslintConfig); fs.writeFileSync(path.join(dir, './.eslintrc.js'), eslintContent); done(); }) ); gulp.task('gen-lint-config', gulp.series('genPrettierrc', 'genEslint')); gulp.task('js', () => { console.log('[Parallel] compile js...'); return babelify(); }); gulp.task('es', () => { console.log('[Parallel] compile es...'); return babelify(false); }); gulp.task('compile', gulp.series('cleanCompile', gulp.parallel('js', 'es', 'css'))); gulp.task( 'js-lint', gulp.series('check-deps', (done) => { const fileList = (argv._ || []).slice(1); if (argv['js-lint'] === false) { return done(); } const eslintBin = require.resolve('eslint/bin/eslint'); let eslintConfig = path.join(__dirname, '../config/eslintrc.js'); const projectEslint = resolveCwd('./.eslintrc'); if (fs.existsSync(projectEslint)) { eslintConfig = projectEslint; } let args = [eslintBin, '-c', eslintConfig]; if (fileList.length) { const regex = /\.jsx?$/i; const jsFiles = fileList.filter((file) => regex.test(file)); if (!jsFiles.length) { done(); return; } args = args.concat(jsFiles); } else { args = args.concat(['--ext', '.js,.jsx']); // eslint v5 will exit when not file find. We have to check first [src, 'tests', 'examples'].forEach((testPath) => { if (glob.sync(`${testPath}/**/*.{js,ssx}`).length) { args.push(testPath); } }); } if (argv.fix) { args.push('--fix'); } runCmd('node', args, done); }) ); gulp.task('lint', gulp.series('js-lint')); function cleanBuild() { if (fs.existsSync(resolveCwd('build'))) { shelljs.rm('-rf', resolveCwd('build')); } } gulp.task('dist', (done) => { const entry = pkg.config && pkg.config.entry; if (!entry) { done(); return; } let webpackConfig; const buildFolder = path.join(cwd, 'dist/'); if (fs.existsSync(path.join(cwd, 'webpack.config.js'))) { webpackConfig = require(path.join(cwd, 'webpack.config.js'))( getWebpackConfig({ common: false, inlineSourceMap: false, }), { phase: 'dist' } ); } else { const output = pkg.config && pkg.config.output; if (output && output.library === null) { output.library = undefined; } webpackConfig = assign( getWebpackConfig({ common: false, inlineSourceMap: false, }), { output: Object.assign( { path: buildFolder, filename: '[name].js', library: pkg.name, libraryTarget: 'umd', libraryExport: 'default', }, output ), externals: { vue: { root: 'Vue', commonjs2: 'vue', commonjs: 'vue', amd: 'vue', }, }, } ); const compressedWebpackConfig = Object.assign({}, webpackConfig); compressedWebpackConfig.entry = {}; Object.keys(entry).forEach((e) => { compressedWebpackConfig.entry[`${e}.min`] = entry[e]; }); compressedWebpackConfig.plugins = webpackConfig.plugins.concat([ new webpack.optimize.UglifyJsPlugin({ compress: { screw_ie8: true, // Vue doesn't support IE8 warnings: false, }, mangle: { screw_ie8: true, }, output: { comments: false, screw_ie8: true, }, }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'), }), ]); webpackConfig.entry = entry; webpackConfig = [webpackConfig, compressedWebpackConfig]; } measureFileSizesBeforeBuild(buildFolder).then((previousFileSizes) => { shelljs.rm('-rf', buildFolder); webpack(webpackConfig, (err, stats) => { if (err) { console.error('error', err); } stats.toJson().children.forEach(printResult); printFileSizesAfterBuild(stats, previousFileSizes, buildFolder); done(err); }); }); }); // gulp.task('gh-pages', ['build'], done => { // console.log('gh-paging'); // if (pkg.scripts['pre-gh-pages']) { // shelljs.exec('npm run pre-gh-pages'); // } // if (fs.existsSync(resolveCwd('./examples/'))) { // const ghPages = require('gh-pages'); // ghPages.publish( // resolveCwd('build'), // { // depth: 1, // logger(message) { // console.log(message); // }, // }, // () => { // cleanBuild(); // console.log('gh-paged'); // done(); // } // ); // } else { // done(); // } // }); // gulp.task('build', ['webpack'], () => { // if (fs.existsSync(resolveCwd('./examples/'))) { // const dir = resolveCwd('./examples/'); // let files = fs.readdirSync(dir); // files = files // .filter(f => f[0] !== '~') // Remove '~tmp' file // .map(f => path.join(dir, f)); // const filesMap = {}; // files.forEach(f => { // filesMap[f] = 1; // }); // files.forEach(f => { // if (f.match(/\.tsx?$/)) { // let js = f.replace(/\.tsx?$/, '.js'); // if (filesMap[js]) { // delete filesMap[js]; // } // js = f.replace(/\.tsx?$/, '.jsx'); // if (filesMap[js]) { // delete filesMap[js]; // } // } // }); // return gulp // .src(Object.keys(filesMap)) // .pipe( // jsx2example({ // dest: 'build/examples/', // }) // ) // jsx2example(options) // .pipe(gulp.dest('build/examples/')); // } // return undefined; // }); function babelifyInternal(js, modules) { function replacer(match, m1, m2) { return `${m1}/assets/${m2}.css`; } const babelConfig = getBabelCommonConfig(modules); if (modules === false) { babelConfig.plugins.push(replaceLib); } let stream = js.pipe(babel(babelConfig)); if (argv.compress) { stream = stream.pipe(minify()); } return stream .pipe( through2.obj(function (file, encoding, next) { const contents = file.contents.toString(encoding).replace(lessPath, replacer); file.contents = Buffer.from(contents); this.push(file); next(); }) ) .pipe(gulp.dest(modules !== false ? 'lib' : 'es')); } function babelify(modules) { const streams = []; const assets = gulp .src([`${src}/**/*.@(png|svg|less|d.ts)`]) .pipe(gulp.dest(modules === false ? 'es' : 'lib')); if (glob.sync('src/**/*.{ts,tsx}').length && !glob.sync('src/**/*.d.ts').length) { let error = 0; let reporter = tsDefaultReporter; if (argv['single-run']) { reporter = { error(e) { tsDefaultReporter.error(e); error = e; }, finish: tsDefaultReporter.finish, }; } const tsResult = gulp .src([`${src}/**/*.ts`, `${src}/**/*.tsx`, 'typings/**/*.d.ts']) .pipe(ts(tsConfig, reporter)); const check = () => { if (error) { console.error('compile error', error); process.exit(1); } }; tsResult.on('finish', check); tsResult.on('end', check); streams.push( tsResult.dts // .pipe(require('gulp-debug')()) .pipe(gulp.dest(modules === false ? 'es' : 'lib')) ); streams.push(babelifyInternal(tsResult.js, modules)); } else { streams.push(babelifyInternal(gulp.src([`${src}/**/*.js`, `${src}/**/*.jsx`]), modules)); } return merge2(streams.concat([assets])); } gulp.task('check-deps', (done) => { if (argv['check-deps'] !== false) { require('./checkDep')(done); } }); gulp.task( 'publish', gulp.series('compile', (done) => { if (!fs.existsSync(resolveCwd('lib')) || !fs.existsSync(resolveCwd('es'))) { return done('missing lib/es dir'); } console.log('publishing'); const npm = argv.tnpm ? 'tnpm' : 'npm'; const beta = !pkg.version.match(/^\d+\.\d+\.\d+$/); let args = [npm, 'publish', '--with-vc-tools']; if (beta) { args = args.concat(['--tag', 'beta']); } else if (argv.tag) { args = args.concat(['--tag', argv.tag]); } if (pkg.scripts['pre-publish']) { shelljs.exec(`npm run pre-publish`); } let ret = shelljs.exec(args.join(' ')).code; cleanCompile(); console.log('published'); if (!ret) { ret = undefined; } done(ret); }) ); gulp.task( 'compile_watch', gulp.series('compile', (done) => { console.log('file changed'); const outDir = argv['out-dir']; if (outDir) { fs.copySync(resolveCwd('lib'), path.join(outDir, 'lib')); fs.copySync(resolveCwd('es'), path.join(outDir, 'es')); if (fs.existsSync(resolveCwd('assets'))) { fs.copySync(resolveCwd('assets'), path.join(outDir, 'assets')); } } done(); }) ); gulp.task('prettier', () => { return gulp .src(['./src/**/*.{js,jsx}', './tests/**/*.{js,jsx}', './examples/**/*.{js,jsx}']) .pipe( prettier.format( { printWidth: 100, useFlowParser: false, singleQuote: true, trailingComma: 'all', }, { reporter: 'error', } ) ) .pipe(gulp.dest((file) => file.base)); }); gulp.task('pre-commit', gulp.series('prettier', 'lint')); gulp.task( 'pub', gulp.series('publish', (done) => { console.log('tagging'); const { version } = pkg; shelljs.cd(cwd); shelljs.exec(`git tag ${version}`); shelljs.exec(`git push origin ${version}:${version}`); shelljs.exec('git push origin master:master'); console.log('tagged'); done(); }) );