chore: various DX improvements like working source maps (#85)
* init changes * sourcemaps work * eff off pbiviz * more fixes * moar fixes * prod build fix * remove yarn field * minor scripts change * moar readme stuff
This commit is contained in:
committed by
GitHub
parent
6e92c857a7
commit
52f4325619
@@ -46,10 +46,6 @@ jobs:
|
||||
name: "npm run build"
|
||||
command: "npm run build"
|
||||
working_directory: src/powerbi-visual
|
||||
- run:
|
||||
name: "npm run pack"
|
||||
command: "npm run pack"
|
||||
working_directory: src/powerbi-visual
|
||||
- store_artifacts:
|
||||
path: dist/*.pbiviz
|
||||
- persist_to_workspace:
|
||||
|
||||
@@ -341,3 +341,6 @@ ASALocalRun/
|
||||
**/webpack.statistics.html
|
||||
**/Thumbs.db
|
||||
installer/
|
||||
|
||||
localhost.pem
|
||||
localhost-key.pem
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "speckle-powerbi",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "root",
|
||||
"path": "."
|
||||
"name": "👀 powerbi-visual",
|
||||
"path": "src/powerbi-visual"
|
||||
},
|
||||
{
|
||||
"name": "DataConnector",
|
||||
"name": "➡️ powerbi-data-connector",
|
||||
"path": "src/powerbi-data-connector"
|
||||
},
|
||||
{
|
||||
"name": "Visual",
|
||||
"path": "src/powerbi-visual"
|
||||
}
|
||||
"name": "🏠 root",
|
||||
"path": "."
|
||||
},
|
||||
],
|
||||
"settings": {
|
||||
"powerquery.general.mode": "SDK",
|
||||
@@ -23,24 +23,30 @@
|
||||
"**/node_modules/**": true,
|
||||
".tmp": true
|
||||
},
|
||||
"files.exclude": {
|
||||
".tmp": true
|
||||
},
|
||||
"search.exclude": {
|
||||
".tmp": true,
|
||||
"typings": true
|
||||
"typings": true,
|
||||
"dist": true,
|
||||
"wepbpack.statistics.dev.html": true,
|
||||
"wepbpack.statistics.html": true,
|
||||
},
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": ["/pbiviz.json"],
|
||||
"fileMatch": [
|
||||
"/pbiviz.json"
|
||||
],
|
||||
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.pbiviz.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": ["/capabilities.json"],
|
||||
"fileMatch": [
|
||||
"/capabilities.json"
|
||||
],
|
||||
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.capabilities.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": ["/dependencies.json"],
|
||||
"fileMatch": [
|
||||
"/dependencies.json"
|
||||
],
|
||||
"url": "./src/powerbi-visual/node_modules/powerbi-visuals-api/schema.dependencies.json"
|
||||
}
|
||||
]
|
||||
@@ -51,4 +57,4 @@
|
||||
"powerquery.vscode-powerquery-sdk"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-4
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"editor.tabSize": 4,
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true,
|
||||
"files.eol": "\n",
|
||||
"files.watcherExclude": {
|
||||
@@ -7,12 +7,10 @@
|
||||
"**/node_modules/**": true,
|
||||
".tmp": true
|
||||
},
|
||||
"files.exclude": {
|
||||
".tmp": true
|
||||
},
|
||||
"files.associations": {
|
||||
"*.resjson": "json"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"search.exclude": {
|
||||
".tmp": true,
|
||||
"typings": true
|
||||
|
||||
@@ -76,6 +76,26 @@ You'll need to properly set up the certificate in order to be able to use the ho
|
||||
|
||||
> Hot Reload will only work on PowerBI Web (**not** on Desktop).
|
||||
|
||||
### Local dev guide (for powerbi-visual)
|
||||
|
||||
1. Cd into `./src/powerbi-visual`
|
||||
1. Run `npm install`
|
||||
1. To ensure proper SSL cert usage
|
||||
1. Ensure [mkcert](https://github.com/FiloSottile/mkcert) is installed
|
||||
1. Run `npm run generate-certs`
|
||||
1. If you're on WSL2, you'll need to copy over the root CA to the Windows side and install it there as a trusted root CA. Typically its in `~/.local/share/mkcert/rootCA.pem` on WSL2. From bash, `cd` to that folder and then do `explorer.exe .` to open it in Windows Explorer and then copy the pem file to someplace better accessible. Then open `crtmgr` and install it into **Trusted Root Certification Authorities**. "Certificates - Current User" > "Trusted Root Certification Authorities" > "Certificates" > Right Click "All Tasks" > "Import" > "Local Machine" > "Place all certificates in the following store" > "Trusted Root Certification Authorities". You may have to set the cert filter to "All Files" to see the `.pem` file.
|
||||
1. After the cert is installed you may have to restart your browser & dev server
|
||||
1. Run `npm run dev`
|
||||
1. PowerBI -> Home > New Report > Paste Or manually enter date > Auto-create > Create
|
||||
1. In the report, click on 'Edit' to open edit mode, and add a "Developer Visual" visual
|
||||
|
||||
#### Source map issues
|
||||
|
||||
Make sure you're running the dev build (`npm run dev`) and in your browser's dev tools trigger "Clear source maps cache" and "Enable JavaScript source maps". When everything's working, you should be able to click on the "App mounted" console message's file reference link which will take you to the source-mapped source code in dev tools.
|
||||
|
||||
Its still a bit janky in that it maye show multiple files with the same name in the file tree,
|
||||
but one of those is gonna be the real fully source mapped one.
|
||||
|
||||
### Contributing
|
||||
|
||||
Please make sure you read the [contribution guidelines](.github/CONTRIBUTING.md) for an overview of the best practices we try to follow.
|
||||
|
||||
Generated
+1658
-403
File diff suppressed because it is too large
Load Diff
@@ -7,10 +7,10 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"pbiviz": "pbiviz",
|
||||
"pack": "webpack --config webpack.config.ts",
|
||||
"build": "webpack --config webpack.config.dev.ts",
|
||||
"serve": "webpack-dev-server --config webpack.config.dev.ts"
|
||||
"generate-certs": "mkcert localhost",
|
||||
"build": "webpack --config webpack.config.ts",
|
||||
"build:dev": "webpack --config webpack.config.dev.ts",
|
||||
"dev": "webpack-dev-server --config webpack.config.dev.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.5",
|
||||
@@ -58,8 +58,8 @@
|
||||
"mini-css-extract-plugin": "^2.7.5",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-import": "^15.1.0",
|
||||
"powerbi-visuals-tools": "^5.4.3",
|
||||
"powerbi-visuals-webpack-plugin": "^4.0.0",
|
||||
"powerbi-visuals-tools": "^5.6.0",
|
||||
"powerbi-visuals-webpack-plugin": "^4.1.0",
|
||||
"prettier": "^2.8.8",
|
||||
"style-loader": "^3.3.2",
|
||||
"tailwindcss": "^3.3.2",
|
||||
@@ -77,4 +77,4 @@
|
||||
"webpack-dev-server": "^4.15.0"
|
||||
},
|
||||
"version": "2.0.0"
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
"displayName": "Speckle PowerBI Viewer",
|
||||
"guid": "specklePowerBiVisual",
|
||||
"visualClassName": "Visual",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.0.0",
|
||||
"description": "An interactive 3D viewer for Speckle Data",
|
||||
"supportUrl": "https://speckle.community",
|
||||
"gitHubUrl": "https://github.com/specklesystems/speckle-powerbi-visuals"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import HomeView from './views/HomeView.vue'
|
||||
import ViewerView from './views/ViewerView.vue'
|
||||
import { computed } from 'vue'
|
||||
import { computed, onMounted } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { storeKey } from 'src/injectionKeys'
|
||||
|
||||
@@ -9,6 +9,10 @@ let store = useStore(storeKey)
|
||||
let status = computed(() => {
|
||||
return store.state.status
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
console.log("App mounted")
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -12,13 +12,12 @@ function goToForum() {
|
||||
function goToGuide() {
|
||||
host.launchUrl('https://speckle.guide/user/powerbi')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
id="speckle-home-view"
|
||||
class="flex flex-col justify-center items-center h-full w-full bg-primary text-center text-foundation"
|
||||
>
|
||||
<div id="speckle-home-view"
|
||||
class="flex flex-col justify-center items-center h-full w-full bg-primary text-center text-foundation">
|
||||
<div class="flex justify-center items-center">
|
||||
<img src="@assets/logo-white.png" alt="Logo" class="w-1/3" />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import path from 'path'
|
||||
|
||||
// api configuration
|
||||
import powerbi from 'powerbi-visuals-api'
|
||||
import ExtraWatchWebpackPlugin from 'extra-watch-webpack-plugin'
|
||||
import { BundleAnalyzerPlugin as Visualizer } from 'webpack-bundle-analyzer'
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
import { PowerBICustomVisualsWebpackPlugin } from 'powerbi-visuals-webpack-plugin'
|
||||
import webpack from 'webpack'
|
||||
import fs from 'fs'
|
||||
import { WebpackConfiguration } from 'webpack-cli'
|
||||
import { VueLoaderPlugin } from 'vue-loader'
|
||||
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'
|
||||
|
||||
/**
|
||||
* MAIN CONSTS
|
||||
*/
|
||||
const devServerPort = 8080
|
||||
const pbivizPath = './pbiviz.json'
|
||||
const capabilitiesPath = './capabilities.json'
|
||||
const pluginLocation = './.tmp/precompile/visualPlugin.ts' // path to visual plugin file, the file generates by the plugin
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const powerbiApi: any = powerbi // Types for PowerBI seem to be off, so I'm instead forcing it to `any`
|
||||
|
||||
// visual configuration json path
|
||||
const pbivizFile = require(path.join(__dirname, pbivizPath))
|
||||
|
||||
const packageJsonFile = require(path.join(__dirname, 'package.json'))
|
||||
pbivizFile.visual.version = packageJsonFile.version
|
||||
|
||||
// the visual capabilities content
|
||||
const capabilitiesFile = require(path.join(__dirname, capabilitiesPath))
|
||||
|
||||
// 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
|
||||
const babelOptions = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
ie: '11'
|
||||
},
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 3,
|
||||
modules: false
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins: [],
|
||||
sourceType: 'unambiguous', // tell to babel that the project can contain different module types, not only es2015 modules
|
||||
cacheDirectory: path.join('.tmp', 'babelCache') // path for cache files
|
||||
}
|
||||
|
||||
export const buildConfig = (params: { mode: 'dev' | 'prod' }) => {
|
||||
const isProd = params.mode === 'prod'
|
||||
|
||||
const loadCert = () => {
|
||||
const keyPath = path.resolve(__dirname, 'localhost-key.pem')
|
||||
const certPath = path.resolve(__dirname, 'localhost.pem')
|
||||
if (!fs.existsSync(keyPath) || !fs.existsSync(certPath)) {
|
||||
console.log('Unable to locate localhost certs, skipping...')
|
||||
return undefined
|
||||
}
|
||||
|
||||
console.log(
|
||||
'Using locally generated localhost certs, make sure the CA cert is installed & trusted!'
|
||||
)
|
||||
return {
|
||||
key: fs.readFileSync(keyPath),
|
||||
cert: fs.readFileSync(certPath)
|
||||
}
|
||||
}
|
||||
const certInfo = isProd ? undefined : loadCert()
|
||||
|
||||
const config: WebpackConfiguration = {
|
||||
entry: {
|
||||
visual: pluginLocation
|
||||
},
|
||||
optimization: {
|
||||
concatenateModules: false,
|
||||
minimize: isProd // enable minimization for create *.pbiviz file less than 2 Mb, can be disabled for dev mode
|
||||
},
|
||||
devtool: isProd ? false : 'inline-source-map',
|
||||
mode: isProd ? 'production' : 'development',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: ['vue-loader']
|
||||
},
|
||||
{
|
||||
parser: {
|
||||
amd: false
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /(\.ts)x|\.ts$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [
|
||||
// '@babel/react',
|
||||
'@babel/env'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: false,
|
||||
experimentalWatchApi: false,
|
||||
appendTsSuffixTo: [/\.vue$/]
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/],
|
||||
include: /.tmp|powerbi-visuals-|src|precompile\\visualPlugin.ts/
|
||||
},
|
||||
{
|
||||
test: /(\.js)x|\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: babelOptions
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/]
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader',
|
||||
type: 'javascript/auto'
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)?$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(woff|ttf|ico|woff2|jpg|jpeg|png|webp|svg)$/i,
|
||||
use: ['base64-inline-loader']
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js', '.css'],
|
||||
alias: {
|
||||
src: path.resolve(__dirname, 'src/'),
|
||||
assets: path.resolve(__dirname, 'assets/')
|
||||
},
|
||||
plugins: [new TsconfigPathsPlugin()]
|
||||
},
|
||||
output: {
|
||||
publicPath: '/assets',
|
||||
path: path.join(__dirname, '/.tmp', 'drop'),
|
||||
library: +powerbiApi.version.replace(/\./g, '') >= 320 ? pbivizFile.visual.guid : undefined,
|
||||
libraryTarget: +powerbiApi.version.replace(/\./g, '') >= 320 ? 'var' : undefined
|
||||
},
|
||||
...(isProd
|
||||
? {}
|
||||
: {
|
||||
devServer: {
|
||||
static: {
|
||||
directory: path.join(__dirname, '.tmp', 'drop'), // path with assets for dev server, they are generated by webpack plugin
|
||||
publicPath: '/assets'
|
||||
},
|
||||
compress: true,
|
||||
port: devServerPort, // dev server port
|
||||
hot: false,
|
||||
...(certInfo
|
||||
? {
|
||||
server: {
|
||||
type: 'https',
|
||||
options: {
|
||||
...certInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
: {
|
||||
https: {}
|
||||
}),
|
||||
liveReload: false,
|
||||
webSocketServer: false,
|
||||
headers: {
|
||||
'access-control-allow-origin': '*',
|
||||
'cache-control': 'public, max-age=0'
|
||||
}
|
||||
}
|
||||
}),
|
||||
externals:
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false'
|
||||
}
|
||||
: {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false',
|
||||
corePowerbiObject: "Function('return this.powerbi')()",
|
||||
realWindow: "Function('return this')()"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
__VUE_OPTIONS_API__: JSON.stringify(true),
|
||||
__VUE_PROD_DEVTOOLS__: JSON.stringify(false)
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
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({
|
||||
paths: [path.join(__dirname, pluginLocation), './.tmp/**/*.*']
|
||||
}),
|
||||
// custom visuals plugin instance with options
|
||||
new PowerBICustomVisualsWebpackPlugin({
|
||||
...pbivizFile,
|
||||
compression: isProd ? 9 : 0,
|
||||
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: isProd,
|
||||
generateResources: true,
|
||||
minifyJS: isProd,
|
||||
minify: isProd,
|
||||
modules: true,
|
||||
visualSourceLocation: '../../src/visual',
|
||||
pluginLocation: pluginLocation,
|
||||
packageOutPath: path.join(__dirname, 'dist')
|
||||
}),
|
||||
new ExtraWatchWebpackPlugin({
|
||||
files: [pbivizPath, capabilitiesPath]
|
||||
}),
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? new webpack.ProvidePlugin({
|
||||
define: 'fakeDefine'
|
||||
})
|
||||
: new webpack.ProvidePlugin({
|
||||
window: 'realWindow',
|
||||
define: 'fakeDefine',
|
||||
powerbi: 'corePowerbiObject'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
@@ -1,228 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import path from 'path'
|
||||
import { buildConfig } from './webpack.config.base'
|
||||
|
||||
// api configuration
|
||||
import powerbi from 'powerbi-visuals-api'
|
||||
import ExtraWatchWebpackPlugin from 'extra-watch-webpack-plugin'
|
||||
import { BundleAnalyzerPlugin as Visualizer } from 'webpack-bundle-analyzer'
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
import { PowerBICustomVisualsWebpackPlugin } from 'powerbi-visuals-webpack-plugin'
|
||||
import webpack from 'webpack'
|
||||
import fs from 'fs'
|
||||
import { WebpackConfiguration } from 'webpack-cli'
|
||||
import { VueLoaderPlugin } from 'vue-loader'
|
||||
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const powerbiApi: any = powerbi // Types for PowerBI seem to be off, so I'm instead forcing it to `any`
|
||||
|
||||
// visual configuration json path
|
||||
const pbivizPath = './pbiviz.json'
|
||||
const pbivizFile = require(path.join(__dirname, pbivizPath))
|
||||
|
||||
const packageJsonFile = require(path.join(__dirname, 'package.json'))
|
||||
pbivizFile.visual.version = packageJsonFile.version
|
||||
|
||||
// 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
|
||||
const babelOptions = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
ie: '11'
|
||||
},
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 3,
|
||||
modules: false
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins: [],
|
||||
sourceType: 'unambiguous', // tell to babel that the project can contain different module types, not only es2015 modules
|
||||
cacheDirectory: path.join('.tmp', 'babelCache') // path for cache files
|
||||
}
|
||||
|
||||
const config: WebpackConfiguration = {
|
||||
entry: {
|
||||
visual: pluginLocation
|
||||
},
|
||||
optimization: {
|
||||
concatenateModules: false,
|
||||
minimize: false // enable minimization for create *.pbiviz file less than 2 Mb, can be disabled for dev mode
|
||||
},
|
||||
devtool: 'source-map',
|
||||
mode: 'development',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: ['vue-loader']
|
||||
},
|
||||
{
|
||||
parser: {
|
||||
amd: false
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /(\.ts)x|\.ts$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [
|
||||
// '@babel/react',
|
||||
'@babel/env'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: false,
|
||||
experimentalWatchApi: false,
|
||||
appendTsSuffixTo: [/\.vue$/]
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/],
|
||||
include: /.tmp|powerbi-visuals-|src|precompile\\visualPlugin.ts/
|
||||
},
|
||||
{
|
||||
test: /(\.js)x|\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: babelOptions
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/]
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader',
|
||||
type: 'javascript/auto'
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)?$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(woff|ttf|ico|woff2|jpg|jpeg|png|webp|svg)$/i,
|
||||
use: ['base64-inline-loader']
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js', '.css'],
|
||||
alias: {
|
||||
src: path.resolve(__dirname, 'src/'),
|
||||
assets: path.resolve(__dirname, 'assets/')
|
||||
},
|
||||
plugins: [new TsconfigPathsPlugin()]
|
||||
},
|
||||
output: {
|
||||
publicPath: '/assets',
|
||||
path: path.join(__dirname, '/.tmp', 'drop'),
|
||||
library: +powerbiApi.version.replace(/\./g, '') >= 320 ? pbivizFile.visual.guid : undefined,
|
||||
libraryTarget: +powerbiApi.version.replace(/\./g, '') >= 320 ? 'var' : undefined
|
||||
},
|
||||
devServer: {
|
||||
static: {
|
||||
directory: path.join(__dirname, '.tmp', 'drop'), // path with assets for dev server, they are generated by webpack plugin
|
||||
publicPath: '/assets'
|
||||
},
|
||||
compress: true,
|
||||
port: 8080, // dev server port
|
||||
hot: false,
|
||||
https: {},
|
||||
liveReload: false,
|
||||
webSocketServer: false,
|
||||
headers: {
|
||||
'access-control-allow-origin': '*',
|
||||
'cache-control': 'public, max-age=0'
|
||||
}
|
||||
},
|
||||
externals:
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false'
|
||||
}
|
||||
: {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false',
|
||||
corePowerbiObject: "Function('return this.powerbi')()",
|
||||
realWindow: "Function('return this')()"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
__VUE_OPTIONS_API__: JSON.stringify(true),
|
||||
__VUE_PROD_DEVTOOLS__: JSON.stringify(false)
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
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({
|
||||
paths: [path.join(__dirname, pluginLocation), './.tmp/**/*.*']
|
||||
}),
|
||||
// custom visuals plugin instance with options
|
||||
new PowerBICustomVisualsWebpackPlugin({
|
||||
...pbivizFile,
|
||||
compression: 0,
|
||||
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: false,
|
||||
generateResources: true,
|
||||
minifyJS: false,
|
||||
minify: false,
|
||||
modules: true,
|
||||
visualSourceLocation: '../../src/visual',
|
||||
pluginLocation: pluginLocation,
|
||||
packageOutPath: path.join(__dirname, 'dist')
|
||||
}),
|
||||
new ExtraWatchWebpackPlugin({
|
||||
files: [pbivizPath, capabilitiesPath]
|
||||
}),
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? new webpack.ProvidePlugin({
|
||||
define: 'fakeDefine'
|
||||
})
|
||||
: new webpack.ProvidePlugin({
|
||||
window: 'realWindow',
|
||||
define: 'fakeDefine',
|
||||
powerbi: 'corePowerbiObject'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default config
|
||||
export default buildConfig({ mode: 'dev' })
|
||||
|
||||
@@ -1,212 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import path from 'path'
|
||||
import { buildConfig } from './webpack.config.base'
|
||||
|
||||
// api configuration
|
||||
import powerbi from 'powerbi-visuals-api'
|
||||
import ExtraWatchWebpackPlugin from 'extra-watch-webpack-plugin'
|
||||
import { BundleAnalyzerPlugin as Visualizer } from 'webpack-bundle-analyzer'
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
||||
import { PowerBICustomVisualsWebpackPlugin } from 'powerbi-visuals-webpack-plugin'
|
||||
import webpack from 'webpack'
|
||||
import fs from 'fs'
|
||||
import { WebpackConfiguration } from 'webpack-cli'
|
||||
import { VueLoaderPlugin } from 'vue-loader'
|
||||
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const powerbiApi: any = powerbi // Types for PowerBI seem to be off, so I'm instead forcing it to `any`
|
||||
|
||||
// visual configuration json path
|
||||
const pbivizPath = './pbiviz.json'
|
||||
const pbivizFile = require(path.join(__dirname, pbivizPath))
|
||||
|
||||
const packageJsonFile = require(path.join(__dirname, 'package.json'))
|
||||
pbivizFile.visual.version = packageJsonFile.version
|
||||
|
||||
// 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
|
||||
const babelOptions = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
ie: '11'
|
||||
},
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 3,
|
||||
modules: false
|
||||
}
|
||||
]
|
||||
],
|
||||
plugins: [],
|
||||
sourceType: 'unambiguous', // tell to babel that the project can contain different module types, not only es2015 modules
|
||||
cacheDirectory: path.join('.tmp', 'babelCache') // path for cache files
|
||||
}
|
||||
|
||||
const config: WebpackConfiguration = {
|
||||
entry: {
|
||||
visual: 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: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.vue$/,
|
||||
use: ['vue-loader']
|
||||
},
|
||||
{
|
||||
parser: {
|
||||
amd: false
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /(\.ts)x|\.ts$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: [
|
||||
// '@babel/react',
|
||||
'@babel/env'
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: false,
|
||||
experimentalWatchApi: false,
|
||||
appendTsSuffixTo: [/\.vue$/]
|
||||
}
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/],
|
||||
include: /.tmp|powerbi-visuals-|src|precompile\\visualPlugin.ts/
|
||||
},
|
||||
{
|
||||
test: /(\.js)x|\.js$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: babelOptions
|
||||
}
|
||||
],
|
||||
exclude: [/node_modules/]
|
||||
},
|
||||
{
|
||||
test: /\.json$/,
|
||||
loader: 'json-loader',
|
||||
type: 'javascript/auto'
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)?$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(woff|ttf|ico|woff2|jpg|jpeg|png|webp|svg)$/i,
|
||||
use: ['base64-inline-loader']
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.jsx', '.js', '.css'],
|
||||
alias: {
|
||||
src: path.resolve(__dirname, 'src/'),
|
||||
assets: path.resolve(__dirname, 'assets/')
|
||||
},
|
||||
plugins: [new TsconfigPathsPlugin()]
|
||||
},
|
||||
output: {
|
||||
publicPath: '/assets',
|
||||
path: path.join(__dirname, '/.tmp', 'drop'),
|
||||
library: +powerbiApi.version.replace(/\./g, '') >= 320 ? pbivizFile.visual.guid : undefined,
|
||||
libraryTarget: +powerbiApi.version.replace(/\./g, '') >= 320 ? 'var' : undefined
|
||||
},
|
||||
externals:
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false'
|
||||
}
|
||||
: {
|
||||
'powerbi-visuals-api': 'null',
|
||||
fakeDefine: 'false',
|
||||
corePowerbiObject: "Function('return this.powerbi')()",
|
||||
realWindow: "Function('return this')()"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
__VUE_OPTIONS_API__: JSON.stringify(true),
|
||||
__VUE_PROD_DEVTOOLS__: JSON.stringify(false)
|
||||
}),
|
||||
new VueLoaderPlugin(),
|
||||
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({
|
||||
paths: [path.join(__dirname, pluginLocation), './.tmp/**/*.*']
|
||||
}),
|
||||
// custom visuals plugin instance with options
|
||||
new PowerBICustomVisualsWebpackPlugin({
|
||||
...pbivizFile,
|
||||
compression: 9,
|
||||
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,
|
||||
minifyJS: true,
|
||||
minify: true,
|
||||
modules: true,
|
||||
visualSourceLocation: '../../src/visual',
|
||||
pluginLocation: pluginLocation,
|
||||
packageOutPath: path.join(__dirname, 'dist')
|
||||
}),
|
||||
new ExtraWatchWebpackPlugin({
|
||||
files: [pbivizPath, capabilitiesPath]
|
||||
}),
|
||||
powerbiApi.version.replace(/\./g, '') >= 320
|
||||
? new webpack.ProvidePlugin({
|
||||
define: 'fakeDefine'
|
||||
})
|
||||
: new webpack.ProvidePlugin({
|
||||
window: 'realWindow',
|
||||
define: 'fakeDefine',
|
||||
powerbi: 'corePowerbiObject'
|
||||
})
|
||||
]
|
||||
}
|
||||
|
||||
export default config
|
||||
export default buildConfig({ mode: 'prod' })
|
||||
|
||||
Reference in New Issue
Block a user