gulpfile.js (211 lines of code) (raw):

/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @emails oncall+i18n_fbt_js * @format * @noflow */ 'use strict'; const {PLUGINS} = require('./babelPlugins'); const moduleMap = require('./moduleMap'); const babelPluginFbtGulp = require('./packages/babel-plugin-fbt/gulpfile'); const {version} = require('./packages/fbt/package.json'); const setGeneratedFilePragmas = require('./setGeneratedFilePragmas'); const del = require('del'); const gulp = require('gulp'); const babel = require('gulp-babel'); const cleanCSS = require('gulp-clean-css'); const concat = require('gulp-concat'); const derequire = require('gulp-derequire'); const flatten = require('gulp-flatten'); const header = require('gulp-header'); const gulpif = require('gulp-if'); const once = require('gulp-once'); const rename = require('gulp-rename'); const rewriteFlowtypedModules = require('gulp-rewrite-flowtyped-modules'); const gulpUtil = require('gulp-util'); const webpackStream = require('webpack-stream'); const paths = { published: 'packages/fbt', dist: 'packages/fbt/dist', lib: 'packages/fbt/lib', license: 'LICENSE', runtime: [ // Individually listing subfolders of `runtime` to allow watching through these symlinks 'runtime/nonfb/**/*.js', 'runtime/shared/**/*.js', 'runtime/shared_deps/**/*.js', '!runtime/**/__tests__/*', '!runtime/**/__mocks__/*', ], runtimeTests: ['runtime/nonfb/**/__tests__/*'], runtimeMocks: ['runtime/nonfb/**/__mocks__/*'], typedModules: ['flow-types/typed-js-modules/*.flow'], css: ['runtime/**/*.css'], }; const COPYRIGHT = 'Copyright (c) Facebook, Inc. and its affiliates.'; const ONCALL_ID = 'oncall+i18n_fbt_js'; const COPYRIGHT_HEADER = `/** * fbt v<%= version %> * * ${COPYRIGHT} * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @${'generated'} * @${'nolint'} * @${'nogrep'} * @emails ${ONCALL_ID} */ `; const buildDist = function (opts) { const webpackOpts = { externals: {}, output: { filename: opts.output, libraryTarget: 'umd', library: 'fbt', }, plugins: [ new webpackStream.webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify( opts.debug ? 'development' : 'production', ), }), new webpackStream.webpack.LoaderOptionsPlugin({ debug: opts.debug, }), ], optimization: { minimize: !opts.debug, }, }; return webpackStream(webpackOpts, null, function (err, stats) { if (err) { throw new gulpUtil.PluginError('webpack', err); } if (stats.compilation.errors.length) { gulpUtil.log('webpack', '\n' + stats.toString({colors: true})); } }); }; const copyLicense = () => gulp.src(paths.license).pipe(gulp.dest(paths.published)); gulp.task('license', gulp.series(copyLicense)); function flatLib(job) { return job .pipe(flatten()) .pipe(setGeneratedFilePragmas(ONCALL_ID)) .pipe(gulp.dest(paths.lib)); } const buildModules = () => flatLib( gulp .src(paths.runtime, {follow: true}) .pipe(once()) .pipe( babel({ plugins: [ ...PLUGINS, require('@babel/plugin-syntax-jsx'), require('babel-plugin-fbt'), require('babel-plugin-fbt-runtime'), [ require('babel-preset-fbjs/plugins/rewrite-modules'), {map: moduleMap}, ], require('@babel/plugin-transform-react-jsx'), ], }), ), ); gulp.task('modules', gulp.series(babelPluginFbtGulp.build, buildModules)); const babelTestPresets = { plugins: [ ...PLUGINS, '@babel/plugin-syntax-jsx', // TODO #81682213 - Bring in shared runtime tests // The fbtCommon map below is only applicable to fbt-test.js, which doesn't // yet run in github ['babel-plugin-fbt', {fbtCommon: {Accept: '...'}}], 'babel-plugin-fbt-runtime', '@babel/plugin-transform-react-jsx', ], }; const transformTests = (src, dest) => gulp .src(src, {follow: true}) .pipe(once()) .pipe(babel(babelTestPresets)) .pipe(flatten()) .pipe(setGeneratedFilePragmas()) .pipe(gulp.dest(dest)); const buildRuntimeTests = () => transformTests(paths.runtimeTests, paths.lib + '/__tests__'); const buildRuntimeMocks = () => transformTests(paths.runtimeMocks, paths.lib + '/__mocks__'); gulp.task( 'test-modules', gulp.series( babelPluginFbtGulp.build, gulp.parallel(buildRuntimeTests, buildRuntimeMocks), ), ); // Copy raw source with rewritten modules to *.js.flow const buildRuntimeFlowJS = () => flatLib( gulp .src(paths.runtime, {follow: true}) .pipe(rename({extname: '.js.flow'})) .pipe(once()) .pipe(rewriteFlowtypedModules({map: moduleMap})), ); const copyFlowTypedModules = () => flatLib(gulp.src(paths.typedModules, {follow: true})); gulp.task('flow', gulp.parallel(buildRuntimeFlowJS, copyFlowTypedModules)); const buildCSS = () => gulp .src(paths.css, {follow: true}) .pipe(once()) .pipe(concat('fbt.css')) .pipe(cleanCSS({advanced: false})) .pipe(header(COPYRIGHT_HEADER, {version})) .pipe(gulp.dest(paths.lib)); gulp.task('css', gulp.series(buildCSS)); const buildDistTask = () => gulp .src('./packages/fbt/lib/FbtPublic.js') .pipe(buildDist({debug: true, output: 'fbt.js'})) .pipe(derequire()) .pipe(gulpif('*.js', header(COPYRIGHT_HEADER, {version}))) .pipe(gulp.dest(paths.dist)); gulp.task('dist', gulp.series('modules', 'css', buildDistTask)); const buildDistMinTask = () => gulp .src('./packages/fbt/lib/FbtPublic.js') .pipe(buildDist({debug: false, output: 'fbt.min.js'})) .pipe(gulpif('*.js', header(COPYRIGHT_HEADER, {version}))) .pipe(gulp.dest(paths.dist)); gulp.task('dist:min', gulp.series('modules', buildDistMinTask)); const cleanTask = () => del([ '.checksums', paths.published + '/*', '!' + paths.published + '/package.json', '!' + paths.published + '/README.md', ]); gulp.task('clean', gulp.parallel(babelPluginFbtGulp.clean, cleanTask)); gulp.task( 'build-runtime', gulp.series( gulp.parallel('license', 'modules', 'test-modules', 'flow'), gulp.series('dist', 'dist:min'), ), ); gulp.task('watch-runtime', () => { gulp.watch( [paths.license].concat( paths.runtime, paths.runtimeTests, paths.runtimeMocks, paths.typedModules, paths.css, ), { cwd: __dirname, ignoreInitial: false, }, function watchRuntimeFbt(done) { gulp.task('build-runtime')(done); }, ); });