Search code examples
javascripttypescriptbackbone.jswebpackbundle

Bundle/CopyJavascript Libraries from Node_Modules (.Net Core proj with TypeScript)


This question might be trivial and easy for a lot of people, but I am having a hard time configuring everything to work properly, would like to learn how this works.

I want to create a client side project in VS2015, however I want to use TypeScript and also some external javascript libraries, like backbone and marionette.

I already configured most of the things, but when running the page I see an error on the console saying 'Marionette is not defined', which makes me think that the libraries (that I previously installed on the project using NPM) are not being copied to wwwroot correctly.

I am using Webpack with a loader to transpile my TypeScript files.

Can someone guide me on the right path? or maybe send me some documentation please?

Here is my package.json

{
  "version": "1.0.0",
  "name": "yourappname",
  "private": true,
  "devDependencies": {
    "clean-webpack-plugin": "^0.1.19",
    "ts-loader": "^4.0.1",
    "typescript": "^2.7.2",
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.11"
  },
  "scripts": {
    "webpack-script": "webpack"
  },
  "-vs-binding": {
    "BeforeBuild": [
      "webpack-script"
    ]
  },
  "dependencies": {
    "@types/backbone": "^1.3.42",
    "@types/backbone.marionette": "^3.3.2",
    "@types/jquery": "^3.3.1",
    "@types/underscore": "^1.8.8",
    "backbone": "^1.3.3",
    "backbone.marionette": "^3.5.1",
    "jquery": "^3.3.1",
    "underscore": "^1.8.3"
  }
}

My webpack.config.js

"use strict"
{
    // Required to form a complete output path
    let path = require('path');

    // Plagin for cleaning up the output folder (bundle) before creating a new one
    const CleanWebpackPlugin = require('clean-webpack-plugin');

    // Path to the output folder
    const bundleFolder = "wwwroot/bundle/";

    module.exports = {
        // Application entry point
        entry: {
            app: ["./Scripts/main.ts"],
            underscore: ['underscore'], 
            jquery: ['jquery'], 
            backbone: ['backbone'], 
            backbonemarionette: ['backbone.marionette']
        },

        // Output file
        output: {
            filename: '[name].js',
            path: path.resolve(__dirname, bundleFolder)
        },
        module: {
            rules: [
              {
                  test: /\.tsx?$/,
                  loader: "ts-loader",
                  exclude: /node_modules/,
              },
            ]
        },
        resolve: {
            extensions: [".tsx", ".ts", ".js"]
        },
        plugins: [
            new CleanWebpackPlugin([bundleFolder])
        ],
        // Include the generation of debugging information within the output file
        // (Required for debugging client scripts)
        devtool: "inline-source-map"
    };
}

My tsconfig.json

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,

    "alwaysStrict": true,

    "allowSyntheticDefaultImports": true,
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ],

    "allowJs": true,
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true
  },

  "include": [ "./Scripts/*" ],
  "compileOnSave": false
}

My main.ts

class MarionetteApp extends Marionette.Application {  //That's the thing not defined in chrome console 'Marionette'
    constructor() {
        super();
        this.on("start", this.initializeAfter);
    }
    initializeAfter() {
        console.log("i am here");
        alert("initialiseAfter called");
    }
}

However from the chrome console, there seems to exist a file there, as you can see here:

enter image description here

Another thing I notice is that, I see a warning in the Dependencies folder in VS and also the Marionette it has a syntax error, it's not defined, why? Here:

enter image description here

Please can someone give me insight on this? what am I doing wrong? Willing to learn how to do it properly!


Solution

  • Use Webpack.ProvidePlugin to define globals

     const Webpack = require('webpack');
    //...
     plugins: [
        new CleanWebpackPlugin([bundleFolder]),
        new Webpack.ProvidePlugin({
              _: 'underscore',
              $: 'jquery',
              jQuery: 'jquery',
              Backbone: 'backbone',
              Bb: 'backbone',
              Marionette: 'backbone.marionette',
              Mn: 'backbone.marionette',
          }),
    
      ]
    

    Also get rid of the multiple entry points, like so

    entry: "./Scripts/main.ts",