const Encore = require('@symfony/webpack-encore'); const { resolve, parse } = require('path'); const { readdir } = require('fs').promises; /** * get the file names inside given directory recursively, limiting to * a given depth in the recursion * * @param string dir the directory * @param int depth the maximum depth to look into */ async function* getFiles(dir, depth, ignored) { const dirents = await readdir(dir, { withFileTypes: true }); for (const dirent of dirents) { const res = resolve(dir, dirent.name); if (dirent.isDirectory()) { if (depth > 0) { yield* getFiles(res, depth - 1, ignored); } } else if (ignored.includes(res)) { continue; } else { yield res; } } }; /** * populate the config of encore in directories inside `'./src'` and * `'./vendor'` and letting them to alter the encore config. * * if a file `chill.webpack.config.js` is found, the default function is * imported and executed. This function receive two arguments: * * - `Encore`, the main encore object * - `chillEntries`: the entries which will be appended to the main `chill` module, * resulting in a chill.js and chill.css file. * */ async function populateConfig(Encore, chillEntries) { // chill-main contains some bootstrap that must be loaded first. // we register them first and, then, store this chill.webpack.config.js file // into `toIgnore`, ignoring it when we loop on other folders. let toIgnore = []; // loop into chill main for await (const f of getFiles('./vendor/chill-project/chill-bundles/src/Bundle/ChillMainBundle/', 1, [])) { let filename = parse(f).base; if (filename === 'chill.webpack.config.js') { configure = require(f); configure(Encore, chillEntries); toIgnore.push(f); } } // loop into other chill bundles for await (const f of getFiles('./vendor/chill-project/chill-bundles/src/Bundle', 2, toIgnore)) { let filename = parse(f).base; if (filename === 'chill.webpack.config.js') { configure = require(f); configure(Encore, chillEntries); } } // loop into other vendors for await (const f of getFiles('./vendor/', 3, toIgnore)) { let filename = parse(f).base; if (filename === 'chill.webpack.config.js') { configure = require(f); configure(Encore, chillEntries); } } // loop into src directory for await (const f of getFiles('./src', 3, [])) { let filename = parse(f).base; if (filename === 'chill.webpack.config.js') { configure = require(f); configure(Encore, chillEntries); } } }; // export the final configuration module.exports = (async () => { // Manually configure the runtime environment if not already configured yet by the "encore" command. // It's useful when you use tools that rely on webpack.config.js file. if (!Encore.isRuntimeEnvironmentConfigured()) { Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); } // basic encore configuration Encore .setOutputPath('public/build/') .setPublicPath('/build') .enableSassLoader(function (options) { // If set to true, Sass won’t print warnings that are caused by dependencies (like bootstrap): // https://sass-lang.com/documentation/js-api/interfaces/options/#quietDeps options.sassOptions.quietDeps = true; options.sassOptions.silenceDeprecations = ['import']; }) .enableVueLoader(() => {}, { version: 3, }) .enableTypeScriptLoader(function (tsConfig){ tsConfig.appendTsSuffixTo = [/\.vue$/]; tsConfig.appendTsxSuffixTo = [/\.vue$/]; // temporary fix for https://github.com/vuejs/vue-loader/issues/1915 and https://github.com/vuejs/core/issues/2855 tsConfig.compilerOptions = {strict: !Encore.isProduction()}; // disable type checking in ts-loader: Vue files are already checked by vue-tsc, // and the generated code (e.g. mergeModels) may use APIs not yet in the bundled @vue/runtime-core types. // see https://github.com/vuejs/core/issues/10331#issuecomment-1938909170 tsConfig.transpileOnly = true; tsConfig.silent = false; }) //.enableForkedTypeScriptTypesChecking() .autoProvidejQuery() .enableSourceMaps(!Encore.isProduction()) .cleanupOutputBeforeBuild() //.enableBuildNotifications() .enableVersioning() .enableSingleRuntimeChunk() .splitEntryChunks() //.addLoader({ test: /\.pdf$/, loader: 'file-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'pdf/' } }) // configure Babel // .configureBabel((config) => { // config.plugins.push('@babel/a-babel-plugin'); // }) // enables and configure @babel/preset-env polyfills // .configureBabelPresetEnv((config) => { // config.useBuiltIns = 'usage'; // config.corejs = '3.23'; // }) ; Encore.addAliases({ translator: resolve(__dirname, './vendor/chill-project/chill-bundles/assets/translator'), }); // populate config with chill entries let chillEntries = []; await populateConfig(Encore, chillEntries); //getting the encore config and appending chill entries config = Encore.getWebpackConfig(); config.entry.chill = chillEntries; if (!Encore.isProduction()) { console.log(config); config.devtool = 'eval-source-map'; } return config; })();