XrmDefinitelyTyped icon indicating copy to clipboard operation
XrmDefinitelyTyped copied to clipboard

[Question] Use XrmQuery with Webpack

Open sowka1995 opened this issue 5 years ago • 4 comments

Hello, I would like to ask if there is any possibility to use XrmQuery with Webpack? In each form where we use XrmQuery we need to add jslib to Form which is not very optimal. I would like to use a Webpack to bundle TS script with XrmQuery and using Sparkle publish one script to Dynamics CRM. I have tried to do this as follows:

  1. I changed dg.xrmquery.web.js to dg.xrmquery.web.ts and added export { XrmQuery, Filter, XQW }; at the end of the file.
  2. In declaration file dg.xrmquery.web.d.ts I need to changed namespace keyword to interface eg. declare namespace XrmQuery to declare interface XrmQuery (because, I cannot use namespace like a type) and remove function keyword.
  3. In dg.xrmquery.web.ts I added types to XrmQuery eg. var XrmQuery: XrmQuery (here is the interface).
  4. Now in my script I can import { XrmQuery } from "dg.xrmquery.web.ts"
  5. Compile script with Webpack and it seems to work but every time I generate types I need to do step 1 do 3. I could write some automaton for this, but maybe there is a better way to do it?

Thank you in advance!

sowka1995 avatar Dec 26 '20 16:12 sowka1995

Did you ever figure anything more out on this?

daryllabar avatar May 15 '21 17:05 daryllabar

Did you ever figure anything more out on this?

Yes, I tried for a couple of hours to setup webpack but without luck. I was able to bundle XrmQuery to the result files and everything works properly but I had a big problem with Intellisense, I couldn't use generated typings for my entities and I didn't understand why. Finally, we resigned from webpack and use only sparkle to build and release pipeline in the Cloud.

sowka1995 avatar May 15 '21 21:05 sowka1995

I figured out how to do this. In your webpack.config add a ProvidePlugin definition to get the file to get loaded anywhere XrmQuery, Filter, or XQW are used. Also install exports-loader (npm install exports-loader --save-dev) and add settings to export out those variables.:

const Webpack = require('webpack');
const Path = require('path');

module.exports = {
    module: {
        rules: [{
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },{
                test: require.resolve("./src/lib/dg.xrmquery.web.min"),
                loader: "exports-loader",
                options:{
                    exports: ["XrmQuery", "Filter", "XQW"]
                }
            },
        ],
    },
    plugins: [
        new Webpack.ProvidePlugin({
            XrmQuery: [Path.resolve(__dirname, "./src/lib/dg.xrmquery.web.min"), "XrmQuery"],
            Filter: [Path.resolve(__dirname, "./src/lib/dg.xrmquery.web.min"), "Filter"],
            XQW: [Path.resolve(__dirname, "./src/lib/dg.xrmquery.web.min"), "XQW"],
        })
    ],
}

this will force the file to get loaded in every file where it is referenced, without having to specify the import. Note sure if XQW is ever used, but it is only getting added if it is actually being used, so I think this problem is solved! Maybe @misoeli should add this to the docs?

daryllabar avatar Jun 21 '21 17:06 daryllabar

Did you ever figure anything more out on this?

Yes, I tried for a couple of hours to setup webpack but without luck. I was able to bundle XrmQuery to the result files and everything works properly but I had a big problem with Intellisense, I couldn't use generated typings for my entities and I didn't understand why. Finally, we resigned from webpack and use only sparkle to build and release pipeline in the Cloud.

Regarding resolving types, this should be added to tsconfig.json

    "typeRoots": [
      "path/to/folder/where/xrmdefinitelytyped/definitions/are",
      "./node_modules/@types"
    ],

And @daryllabar answer should be accepted if we want to use XrmQuery with WebPack as-is.

Here is another config if using from create-react-app and react-app-rewired.

config-overrides.js

const Path = require("path");
const Webpack = require('webpack');
const reactScriptsPaths = require('react-scripts/config/paths');

module.exports = {
  webpack: function (config, env) {
    //Add XrmDefinitelyTyped
    let xrmDefinitelyTypedPlugin = new Webpack.ProvidePlugin({
      XrmQuery: [Path.resolve(reactScriptsPaths.appNodeModules, "@deaccrm/xrmtypings/dg.xrmquery.web"), "XrmQuery"],
      Filter: [Path.resolve(reactScriptsPaths.appNodeModules, "@deaccrm/xrmtypings/dg.xrmquery.web"), "Filter"],
      XQW: [Path.resolve(reactScriptsPaths.appNodeModules, "@deaccrm/xrmtypings/dg.xrmquery.web"), "XQW"],
    });
    let xrmDefinitelyTypedExportsLoaderRule = {
      test: require.resolve(Path.resolve(reactScriptsPaths.appNodeModules, "@deaccrm/xrmtypings/dg.xrmquery.web")),
      loader: "exports-loader",
      options:{
          exports: ["XrmQuery", "Filter", "XQW"]
      }
    };
    config.plugins.push(xrmDefinitelyTypedPlugin);
    config.module.rules.push(xrmDefinitelyTypedExportsLoaderRule);

    
    return config;
  }
}

janis-veinbergs avatar Feb 28 '23 11:02 janis-veinbergs