/* eslint-env node */ const path = require('path'); const webpack = require('webpack'); const MemoryFileSystem = require('memory-fs'); const EnhancedResolve = require('enhanced-resolve'); const transform = require('transform-jest-deps'); const babel = require('babel-jest'); const createConfig = require('../build/utils/createWebpackConfig'); const SyncNodeJsInputFileSystem = EnhancedResolve.SyncNodeJsInputFileSystem; // Create test webpack config const config = createConfig('test', { isTestRunner: true, platform: 'test' }); // Store FS among preprocess calls const memoryFs = new MemoryFileSystem(); const syncFs = new SyncNodeJsInputFileSystem(); // Filter all loaders const shimLoaders = config.module.rules.filter( (rule) => rule.loader && rule.loader.indexOf('exports-loader') !== -1 ); const specialLoaders = config.module.rules.filter( (rule) => rule.loader && rule.loader.indexOf('raw-loader') !== -1 ); const babelLoaders = config.module.rules.filter( (rule) => rule.loader && rule.loader.indexOf('babel') >= 0 ); const aliasResolver = EnhancedResolve.create.sync(config.resolve); function aliasPreprocessor(src, filename) { return transform(src, { sourceType: 'module' }, (name) => { try { const resolved = aliasResolver({}, process.cwd(), name); return path.normalize(resolved, process.cwd()); } catch (e) { return name; } }); } function webpackPreprocessor(filename) { const options = Object.assign(config, { entry: path.normalize(filename, process.cwd()), output: { path: '/', filename: filename, libraryTarget: 'commonjs2' }, devtool: 'eval' // Fastest devtool }); const compiler = webpack(options); compiler.outputFileSystem = memoryFs; compiler.inputFileSystem = syncFs; let stats = null; compiler.run((err, compilationStats) => { stats = compilationStats; }); while (stats === null) { require('deasync').sleep(10); } return stats.compilation.assets[filename].source(); } module.exports = { process: (src, filename) => { // This transforms with Babel all JS files that doesn't match `exclude` if (!babelLoaders.find((l) => new RegExp(l.exclude).test(filename))) { src = babel.process(src, filename); } // This transforms with Babel all JS files which are not in `node_modules` // Files in ``/app/js/libs/`` still need to be sent to aliasPreprocessor // because they might require modules aliased in webpack // e.g. `backbone` requires `jquery` if (!babelLoaders.find((l) => new RegExp(/node_modules[\/\\]/).test(filename))) { // Use aliases from webpack config src = aliasPreprocessor(src, filename); } const hasShims = shimLoaders.some( (loader) => new RegExp(loader.test).test(filename) ); const hasSpecialRequires = specialLoaders.some( (loader) => src.match(loader.test) ); if (hasShims || hasSpecialRequires) { // Use shims from webpack config src = webpackPreprocessor(filename); } return src; } };