const path = require('path'); const fs = require("fs"); // werbpack plugin const webpack = require("webpack"); const PowerBICustomVisualsWebpackPlugin = require('powerbi-visuals-webpack-plugin'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const Visualizer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const ExtraWatchWebpackPlugin = require('extra-watch-webpack-plugin'); // api configuration const powerbiApi = require("powerbi-visuals-api"); // visual configuration json path const pbivizPath = "./pbiviz.json"; const pbivizFile = require(path.join(__dirname, pbivizPath)); // the visual capabilities content const capabilitiesPath = "./capabilities.json"; const capabilitiesFile = require(path.join(__dirname, capabilitiesPath)); const pluginLocation = './.tmp/precompile/visualPlugin.ts'; // path to visual plugin file, the file generates by the plugin // string resources const resourcesFolder = path.join(".","stringResources"); const localizationFolders = fs.existsSync(resourcesFolder) && fs.readdirSync(resourcesFolder); const statsLocation = "../../webpack.statistics.html"; // babel options to support IE11 let babelOptions = { "presets": [ [ require.resolve('@babel/preset-env'), { "targets": { "ie": "11" }, useBuiltIns: "entry", corejs: 3, modules: false } ] ], sourceType: "unambiguous", // tell to babel that the project can contains different module types, not only es2015 modules cacheDirectory: path.join(".tmp", "babelCache") // path for chace files }; module.exports = { entry: { "visual.js": pluginLocation }, optimization: { concatenateModules: false, minimize: true // enable minimization for create *.pbiviz file less than 2 Mb, can be disabled for dev mode }, devtool: 'source-map', mode: "development", module: { rules: [ { parser: { amd: false } }, { test: /(\.ts)x|\.ts$/, include: /powerbi-visuals-|src|precompile\\visualPlugin.ts/, use: [ { loader: require.resolve('babel-loader'), options: babelOptions }, { loader: require.resolve('ts-loader'), options: { transpileOnly: false, experimentalWatchApi: false } } ] }, { test: /(\.js)x|\.js$/, use: [ { loader: require.resolve('babel-loader'), options: babelOptions } ] }, { test: /\.json$/, loader: require.resolve('json-loader'), type: "javascript/auto" }, { test: /\.less$/, use: [ { loader: MiniCssExtractPlugin.loader }, { loader: require.resolve('css-loader') }, { loader: require.resolve('less-loader'), options: { paths: [path.resolve(__dirname, "..", 'node_modules')] } } ] }, { test: /\.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, { loader: require.resolve('css-loader') } ] }, { test: /\.(woff|ttf|ico|woff2|jpg|jpeg|png|webp)$/i, use: [ { loader: 'base64-inline-loader' } ] } ] }, resolve: { extensions: ['.tsx', '.ts', '.jsx', '.js', '.css'] }, output: { path: path.join(__dirname, "/.tmp","drop"), publicPath: 'assets', filename: "[name]", }, devServer: { disableHostCheck: true, contentBase: path.join(__dirname, ".tmp", "drop"), // path with assets for dev server, they are generated by webpack plugin compress: true, port: 8080, // dev server port hot: false, inline: false, // cert files for dev server https: { pfx: fs.readFileSync("C:\\Users\\littl\\AppData\\Roaming\\npm\\node_modules\\powerbi-visuals-tools\\certs\\PowerBICustomVisualTest_public.pfx"), // for windows passphrase: "5573455193282877" // keep it commented to use webpack generated certificate // key: path.join(__dirname, "certs","PowerBICustomVisualTest_public.key"), // for darwin, linux // cert: path.join(__dirname, "certs", "PowerBICustomVisualTest_public.cer"), // for darwin, linux // pfx: fs.readFileSync(path.join(__dirname, "certs", "PowerBICustomVisualTest_public.pfx")), // for windows // passphrase: "5031595470751755" }, headers: { "access-control-allow-origin": "*", "cache-control": "public, max-age=0" }, }, externals: { "powerbi-visuals-api": 'null', "fakeDefine": 'false', "corePowerbiObject": "Function('return this.powerbi')()", "realWindow": "Function('return this')()" }, plugins: [ new MiniCssExtractPlugin({ filename: "visual.css", chunkFilename: "[id].css" }), new Visualizer({ reportFilename: statsLocation, openAnalyzer: false, analyzerMode: `static` }), // visual plugin regenerates with the visual source, but it does not require relaunching dev server new webpack.WatchIgnorePlugin([ path.join(__dirname, pluginLocation), "./.tmp/**/*.*" ]), // custom visuals plugin instance with options new PowerBICustomVisualsWebpackPlugin({ ...pbivizFile, capabilities: capabilitiesFile, stringResources: localizationFolders && localizationFolders.map(localization => path.join( resourcesFolder, localization, "resources.resjson" )), apiVersion: powerbiApi.version, capabilitiesSchema: powerbiApi.schemas.capabilities, pbivizSchema: powerbiApi.schemas.pbiviz, stringResourcesSchema: powerbiApi.schemas.stringResources, dependenciesSchema: powerbiApi.schemas.dependencies, devMode: false, generatePbiviz: true, generateResources: true, modules: true, visualSourceLocation: "../../src/visual", pluginLocation: pluginLocation, packageOutPath: path.join(__dirname, "dist") }), new ExtraWatchWebpackPlugin({ files: [ pbivizPath, capabilitiesPath ] }), new webpack.ProvidePlugin({ //window: 'realWindow',//for global window.jquery define: 'fakeDefine', powerbi: 'corePowerbiObject' }), ] };