Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

powerbi-visuals-webpack-plugin

microsoft9.2kMIT4.3.1

PowerBI Custom Visuals webpack plugin

custom, visuals, powerbi, visualization, analytics

readme

powerbi-visuals-webpack-plugin

Build npm version npm

This plugin allows developing custom visuals by using webpack to build a visual package.

Provides following functionality:

  • Creates assets for developer server
  • Creates *.pbiviz package.

How to use the plugin

Plugin options

Plugin config description

  const defaultOptions = {
      visual: {
        name: "Visual name",
        displayName: "Visual name for displaying in visuals panel",
        guid: `Unique GUID for the visual (generated by plugin)`,
        visualClassName: "Visual class name, it is used by visual plugin to create instance of the visual",
        version: "Visual version",
        description: "Visual description",
        supportUrl: "URL for support"
    },
    author: "Author of the visual",
    apiVersion: "API version"
    capabilities: {
        // Visual capabilities
    },
    iconImage: "Icon file as base64 string",
    devMode: "development mode",
    packageOutPath: "location to create *.pbiviz file",
    generateResources: "it is used --resources flag in pbiviz tools",
    generatePbiviz: "it is used by --no-pbiviz flag in pbiviz tools"
  };

How to build a visual with webpack

  1. Install all required libraries to build a visual

     npm i webpack webpack-cli powerbi-visuals-webpack-plugin mini-css-extract-plugin webpack-bundle-analyzer extra-watch-webpack-plugin ts-loader json-loader less-loader less css-loader webpack-dev-server --save-dev
  2. Install optional libraries to build JSX files

    If you aren't going to build JSX files, then you can skip this step and delete all babel in section 5.

     npm i @babel/preset-react @babel/runtime @babel/runtime-corejs3 @babel/core @babel/preset-env babel-loader --save-dev
  3. Install the latest version of API package

     npm i powerbi-visuals-api --save
  4. Create SSL certificates (optional)

    You need generate SSL certificates manually or copy files from powerbi-visuals-tools instance.

    Read more about certificates in documentation.

    Also, you can use certificates from powerbi-visuals-tools or use autogenerated certificates by webpack-dev-server. Just skip section 4 to use webpack-dev-server certificates.

    4.1 Run the following command:

         npm i powerbi-visuals-tools@latest --save-dev

    to install the latest version of tools

    4.2 create script command to generate certificate.

    Add into scripts section of package.json command "cert": "pbiviz --install-cert":

     ...
         "scripts": {
             "cert": "pbiviz --install-cert"
         },
     ...

    Execute command npm run cert. You should get message:

         error  Certificate not found. The new certificate will be generated
         info   Certificate generated. Location is <visual root>\node_modules\powerbi-visuals-tools\certs\PowerBICustomVisualTest_public.pfx. Passphrase is '<YOUR_PASSPHRASE>'

    Apply path node_modules\powerbi-visuals-tools\certs\PowerBICustomVisualTest_public.pfx in webpack.config.js at https section of devServer parameters:

     ...
         https: {
             pfx: fs.readFileSync(path.join(__dirname, `node_modules/powerbi-visuals-tools/certs/PowerBICustomVisualTest_public.pfx`)), // for windows
             passphrase: "<YOUR_PASSPHRASE>",
             requestCert: true
         },
     ...
  5. Use sample of config webpack 5. (copy into webpack.config.js)

     const path = require("path");
    
     // webpack
     const webpack = require("webpack");
     const { PowerBICustomVisualsWebpackPlugin, LocalizationLoader } = require('powerbi-visuals-webpack-plugin');
     const MiniCssExtractPlugin = require("mini-css-extract-plugin");
     const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
     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 capabilities = require(path.join(__dirname, capabilitiesPath));
    
     const pluginLocation = "./.tmp/precompile/visualPlugin.ts"; // Path to visual plugin file, the file generated by the webpack-plugin
     const visualSourceLocation = "../../src/visual" // This path is used inside of the generated plugin, so it depends on pluginLocation
     const statsLocation = "../../webpack.statistics.html";
    
     const babelOptions = {
         presets: [
             [
                 require.resolve('@babel/preset-env'),
                 {
                     "targets": {
                         "ie": "11"
                     },
                     useBuiltIns: "entry",
                     corejs: 3,
                     modules: false
                 }
             ],
             "@babel/preset-react" // required for jsx files
         ],
         sourceType: "unambiguous", // tell to babel that the project can contains different module types, not only es2015 modules
         cacheDirectory: path.join(".tmp", "babelCache") // path for cache files
     };
    
     const isProduction = true
     module.exports = {
         entry: {
             "visual.js": pluginLocation,
         },
         target: "web",
         devtool: "source-map",
         mode: isProduction ? "production" : "development",
         optimization: {
             minimize: isProduction, // enable minimization for create *.pbiviz file less than 2 Mb, can be disabled for dev mode
         },
         performance: {
             maxEntrypointSize: 1024000,
             maxAssetSize: 1024000
         },
         module: {
             rules: [
                 {
                     test: /\.tsx?$/,
                     exclude: /node_modules/,
                     include: /powerbi-visuals-|src|precompile(\\|\/)visualPlugin.ts/,
                     use: [
                         {
                             loader: require.resolve('babel-loader'),
                             options: babelOptions
                         },
                         {
                             loader: "ts-loader",
                             options: {
                                 transpileOnly: false,
                                 experimentalWatchApi: false
                             }
                         }
                     ],
                 },
                 {
                     test: /(\.js)x|\.js$/,
                     use: [
                         {
                             loader: require.resolve('babel-loader'),
                             options: babelOptions
                         }
                     ]
                 },
                 {
                     test: /\.json$/,
                     loader: 'json-loader',
                     type: "javascript/auto"
                 },
                 {
                     test: /(\.less)|(\.css)$/,
                     use: [
                         {
                             loader: MiniCssExtractPlugin.loader
                         },
                         {
                             loader: 'css-loader'
                         },
                         {
                             loader: 'less-loader',
                             options: {
                                 lessOptions: {
                                     paths: [path.resolve(__dirname, 'node_modules')]
                                 }
                             }
                         }
                     ]
                 },
                 {
                     test: /\.(woff|ttf|ico|woff2|jpg|jpeg|png|webp|gif|svg|eot)$/i,
                     type: 'asset/inline'
                 },
                 { 
                     test: /powerbiGlobalizeLocales\.js$/,
                     loader: LocalizationLoader
                 }
             ],
         },
         externals: { "powerbi-visuals-api": "null" },
         resolve: {
             extensions: [".tsx", ".ts", ".jsx", ".js", ".css"],
         },
         output: {
             clean: true,
             path: path.join(__dirname, ".tmp", "drop"),
             publicPath: 'assets',
             filename: "[name]",
             library: pbivizFile.visual.guid,
             libraryTarget: "var",
         },
         devServer: {
             static: {
                 directory: path.join(__dirname, ".tmp", "drop"), // path with assets generated by webpack plugin
                 publicPath: '/assets/'
             },
             compress: true, // enable gzip compression
             port: 8080, // dev server port
             hot: false,
             server: { // cert files for dev server
                 type: "https",
                 options: {
                     // 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"
                     // requestCert: true,
                 }
             },
             headers: {
                 "access-control-allow-origin": "*",
                 "cache-control": "public, max-age=0",
             }
         },
         plugins: [
             new MiniCssExtractPlugin({
                 filename: "visual.css",
                 chunkFilename: "[id].css"
             }),
             new BundleAnalyzerPlugin({ // adds the ability to analyze the size of the bundle
                 reportFilename: statsLocation,
                 openAnalyzer: false,
                 analyzerMode: `static`
             }),
             new PowerBICustomVisualsWebpackPlugin({ // custom visuals plugin instance with options
                 ...pbivizFile,
                 capabilities,
                 visualSourceLocation,
                 pluginLocation,
                 apiVersion: powerbiApi.version,
                 capabilitiesSchema: powerbiApi.schemas.capabilities,
                 dependenciesSchema: powerbiApi.schemas.dependencies,
                 devMode: false,
                 generatePbiviz: true,
                 generateResources: isProduction,
                 modules: true,
                 packageOutPath: path.join(__dirname, "dist"),
             }),
             new ExtraWatchWebpackPlugin({
                 files: [pbivizPath, capabilitiesPath],
             }),
             new webpack.WatchIgnorePlugin({ // visual plugin regenerates with the visual source, but it does not require relaunching dev server
                 paths: [
                     path.join(__dirname, pluginLocation),
                     "./.tmp/**/*.*",
                     "./.tmp/**/**/*.*"
                 ]
             }),
             new webpack.ProvidePlugin({
                 define: "fakeDefine",
             }),
         ],
     };
  6. Add new script to build a visual package

    Add new command "package": "webpack" into scripts section of package.json:

     "scripts": {
         "cert": "pbiviz --install-cert",
         "package": "webpack"
     }

    Run npm run package command to create visual package.

Add webpack-dev-server package to debug custom visual

Install webpack-dev-server:

npm i webpack-dev-server --save-dev

Add command "start": "webpack serve" into scripts section of package.json :

"scripts": {
    "cert": "pbiviz --install-cert",
    "package": "webpack",
    "start": "webpack serve"
}

Run command npm run start to start dev server.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

changelog

Change Log - PowerBI visual webpack plugin

This page contains information about changes to the PowerBI-visuals-webpack-plugin.

4.3.1

  • Extended audit for network calls

4.3.0

  • Added support for dynamic {capabilities.js, dependencies.js} configs

4.2.0

  • New property certificationAudit to audit network calls in the visual.
  • New property certificationFix to remove network calls from the visual build. This option is useful for certified visuals. It'll make sure that no forbidden network calls are present in the visual. Test the visual before publishing, since removing these calls might break the visual in some cases.

4.0.2

  • Updated ReadMe
  • Removed redundant options

4.0.1

  • Fixed error when creating new visual plugin
  • Updated packages

4.0.0

  • Implemented localization loader to reduce size of locales in custom visual

3.2.1

  • update visual plugin template to support TS strict mode

3.2.0

  • Fixed broken minification in pbiviz.json
  • Updated packages

⚠ Breaking Chages

  • Now pbiviz.json is not a webpack asset
  • externalJS and cssStyles options are deprecated

3.1.2

  • Fixed bug when css asset wasn't generated

3.1.1

  • Fixed double webpack compilation
  • Removed non-personal environment logging
  • Updated deprecated methods

3.0.0

  • Refactored assets compilation due to latest webpack rules
  • Added non-personal environment logging

2.3.1

  • Fixed plugin template for visuals with powerbi-visuals-api < 3.8.0

2.3.0

  • Added support for CV modal dialog

2.2.6

  • Removed lodash.template usage;

2.2.4

  • Fix VisualPlugin template: convert to required parameter

2.2.3

  • Plugin adds tools version into visual package

2.2.2

  • Fix generating visual plugin folder and dist folder on build
  • Update webpack configuration sample

2.2.1

  • Fix VisualPlugin template.

2.2.0

  • Update VisualPlugin template. Remove no implicit Any types to allow 'noImplicitAny' configuration in tsconfig.

2.1.4

  • Lodash was substituted by certain packages for deepClone() and template() functions

2.1.3

  • Adding support for Python script visuals
  • Fixing logic for replacing source files in scripts

2.1.2

  • Fix loading R script into visuals

2.1.1

  • The new visualPlugin template with default export of visualPlugin object

2.1.0

  • Compression option for compressing visual package

2.0.1

  • Define powerbi variable if it was not defined in window object.
  • Log in console JSON validation fails.

2.0.0

  • Update visual template.

    Note: window object injection required;

  • The plugin clears drop folder - fixed.

1.x.x

  • PowerBI Custom Visuals webpack plugin release. Fix bugs