UNPKG

@hso/d365-cli

Version:

Dynamics 365 Command Line Interface for TypeScript projects for Dataverse

181 lines (173 loc) 6.41 kB
// @ts-ignore import path from 'path'; // @ts-ignore import webpack from 'webpack'; import ESLintPlugin from 'eslint-webpack-plugin'; // @ts-ignore import CopyWebpackPlugin from 'copy-webpack-plugin'; // @ts-ignore import MiniCssExtractPlugin from 'mini-css-extract-plugin'; // @ts-ignore import TerserPlugin from 'terser-webpack-plugin'; // @ts-ignore import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin'; // @ts-ignore import packageJson from './package.json'; // @ts-ignore import crmJson from '../crm.json'; const publisherPrefix = crmJson.crm.publisher_prefix; const namespace = crmJson.crm.namespace; const dir_build = path.resolve(__dirname, `dist/${publisherPrefix}_/${namespace}`); import * as shell from 'shelljs'; import * as fs from 'fs'; interface BuildJson { forms: FormJson[]; webresources: WebresourceJson[]; } interface FormJson { name: string; build: boolean; } interface WebresourceJson extends FormJson { template: 'React' | 'HTML'; } interface Entry { [index: string]: string[]; } const buildFiles = shell.ls('./src/**/build.json'); const entry: Entry = {}; for (const filepath of buildFiles) { const pathSplit = filepath.split('/'); const entityName = pathSplit[pathSplit.length - 2]; const buildJsonString = String(fs.readFileSync(filepath)); const buildJson = JSON.parse(buildJsonString) as BuildJson; for (const form of buildJson.forms) { const {name, build} = form; if (build) { const isTsPath = fs.existsSync(path.resolve(__dirname, `src/${entityName}/${name}/${name}.ts`)); const isTsxPath = fs.existsSync(path.resolve(__dirname, `src/${entityName}/${name}/${name}.tsx`)); const extension = isTsPath ? 'ts' : isTsxPath ? 'tsx' : 'js'; entry[`${entityName}%_%${name}`] = { // @ts-ignore import: path.resolve(__dirname, `src/${entityName}/${name}/${name}.${extension}`), filename: `${entityName}/${name}.js`, library: { name: [publisherPrefix, namespace, entityName, name], type: 'var' }, }; } } for (const webresource of buildJson.webresources) { const {name, build, template} = webresource; if (build) { entry[`${entityName}%_%${name}`] = { // @ts-ignore import: path.resolve(__dirname, `src/${entityName}/${name}.${template === 'React' ? 'tsx' : 'ts'}`), filename: `${entityName}/${name}.js`, library: { name: [publisherPrefix, namespace, name], type: 'var' }, }; } } } // eslint-disable-next-line max-lines-per-function const configFunction = (env: unknown, argv: {mode: string }): unknown => { const mode = argv.mode; const scssLoaders = [mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']; const cssLoaders = [mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']; return { mode: mode, entry: entry, output: { path: dir_build, }, resolve: { extensions: ['.js', '.json', '.ts', '.tsx'] }, devServer: { static: path.resolve(__dirname, `dist/${publisherPrefix}_`), hot: true, }, module: { rules: [{ test: /\.scss$/, use: scssLoaders, }, { test: /\.css$/, use: cssLoaders, }, { test: /\.tsx?$/, use: 'ts-loader', }] }, plugins: [ new webpack.NoEmitOnErrorsPlugin(), new webpack.ids.HashedModuleIdsPlugin(), // so that file hashes don't change unexpectedly new webpack.IgnorePlugin({resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/}), new webpack.BannerPlugin(`${packageJson.description} ${packageJson.version} | (c) HSO Innovation`), new MiniCssExtractPlugin({ filename: (pathData: any) => { const nameSplit = pathData.chunk.name.split('%_%'); return `${nameSplit[0]}/${nameSplit[1]}.css`; }, }), new ESLintPlugin({ extensions: ['ts', 'tsx'], }), // Fix Microsoft CE Validation tool new ReplaceInFileWebpackPlugin([{ dir: dir_build, test: /\.js$/, rules: [{ search: /"==typeof/g, replace: '"===typeof' }, { search: /"!=typeof/g, replace: '"!==typeof' }] }]), ].concat(mode === 'development' ? [ new CopyWebpackPlugin({ patterns: [{ from: './**/**.html', to: dir_build, context: 'src', noErrorOnMissing: true, }] }), ] : [ new CopyWebpackPlugin({ patterns: [{ from: './**/**.(html|png|svg)', to: dir_build, context: 'src', noErrorOnMissing: true, }, { from: 'locales/*', to: dir_build, context: 'src/translation', noErrorOnMissing: true, }] }), ]), stats: { colors: true }, optimization: { minimize: mode === 'production', minimizer: [new TerserPlugin({ extractComments: false, terserOptions: { compress: { drop_console: mode === 'production' } } })] }, devtool: mode === 'development' ? 'source-map' : false, }; }; export default configFunction;