import generator from '@babel/generator'; import { transformSync } from '@babel/core'; import type { Program } from '@babel/types'; import { debug } from '@linaria/logger'; import type { Evaluator, StrictOptions } from '@linaria/babel-preset'; import { buildOptions } from '@linaria/babel-preset'; import shake from './shaker'; function prepareForShake( filename: string, options: StrictOptions, code: string ): Program { const transformOptions = buildOptions(filename, options); transformOptions.ast = true; transformOptions.presets!.unshift([ require.resolve('@babel/preset-env'), { targets: 'ie 11', // we need this plugin so we list it explicitly, explanation in `packages/extractor/src/index` include: ['@babel/plugin-transform-template-literals'], }, ]); transformOptions.presets!.unshift([ require.resolve('@linaria/preeval'), options, ]); transformOptions.plugins!.unshift( require.resolve('babel-plugin-transform-react-remove-prop-types') ); transformOptions.plugins!.unshift([ require.resolve('@babel/plugin-transform-runtime'), { useESModules: false }, ]); debug( 'evaluator:shaker:transform', `Transform ${filename} with options ${JSON.stringify( transformOptions, null, 2 )}` ); const transformed = transformSync(code, transformOptions); if (transformed === null || !transformed.ast) { throw new Error(`${filename} cannot be transformed`); } return transformed.ast.program; } const shaker: Evaluator = (filename, options, text, only = null) => { const [shaken, imports] = shake( prepareForShake(filename, options, text), only ); debug('evaluator:shaker:generate', `Generate shaken source code ${filename}`); const { code: shakenCode } = generator(shaken!); return [shakenCode, imports]; }; export default shaker;