3

I'm having a hard time trying to make Webpack 4 config work. Firstly, I'm not running on a Node.js server; i'm on IIS using .Net MVC. How would I be able to load local js files in my webpack config file?

Here's what my webpack.config.js looks like:

const webpack = require('webpack');
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    mode: 'development',
    entry: {
        'ICC.js':
        [
            path.resolve(__dirname, 'Scripts/dependencies.js'),
            path.resolve(__dirname, 'Scripts/ICC/Helpers.js'),
            path.resolve(__dirname, 'Scripts/ICC/Layout.js'),
            path.resolve(__dirname, 'Scripts/ICC/ICC_Chart.js'),
            path.resolve(__dirname, 'Scripts/ICC/AddModDel.js'),
            path.resolve(__dirname, 'Scripts/Cache/CacheClientTemplate.js'),
            path.resolve(__dirname, 'Scripts/ICC/Menu_ICC.js'),
            path.resolve(__dirname, 'Scripts/ICC/ICCObjetLie.js'),
            path.resolve(__dirname, 'Scripts/Observable/observable.js'),
            path.resolve(__dirname, 'Scripts/Soumission/produitLigne.js'),
            path.resolve(__dirname, 'Scripts/Soumission/soumission.js'),
            path.resolve(__dirname, 'Scripts/Soumission/livraison.js'),
            path.resolve(__dirname, 'Scripts/Soumission/transport.js'),
            path.resolve(__dirname, 'Scripts/Soumission/termes.js'),
            path.resolve(__dirname, 'Scripts/Soumission/contacts.js'),
            path.resolve(__dirname, 'Scripts/Soumission/Recherche/minicart.js'),
            path.resolve(__dirname, 'Scripts/Soumission/Recherche/produitRecherche.js'),
            path.resolve(__dirname, 'Scripts/Content/content.js'),
            path.resolve(__dirname, 'Scripts/Opportunite/competiteur.js'),
            path.resolve(__dirname, 'Scripts/Cookie/cookie.js')
        ]
    },
    devtool: "source-map",
    output: {
        filename: '[name]',
        path: path.resolve(__dirname, './dist/scripts')
    },
    module: {
        rules:
        [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                parser: {
                    amd: false, // disable AMD
                    commonjs: false // disable CommonJS
                }
            }
        ],
    },
    optimization: {
        minimize: true,
        minimizer: [new UglifyJsPlugin({
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
        })]
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx']
    },
    plugins: [
        new CleanWebpackPlugin(['./dist'])
    ]
};

In my dependencies.js, i have the following:

function loaddependencies(scripts) {
    for (var i = 0, len = scripts.length; i < len; i++) {
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = scripts[i];
        var x = document.getElementsByTagName('head')[0];
        x.appendChild(s);
    }
}

var dependencies =
    [
        "~/Scripts/jquery/jquery.min.js",
        "~/Scripts/cldr/cldr.js",
        "~/Scripts/cldr/event.js",
        "~/Scripts/cldr/supplemental.js",
        "~/Scripts/globalize/globalize.js",
        "~/Scripts/globalize/message.js",
        "~/Scripts/globalize/number.js",
        "~/Scripts/globalize/currency.js",
        "~/Scripts/globalize/date.js",
        "~/Scripts/bootstrap/bootstrap.min.js",
        "~/Scripts/splitter/jquery.splitter.js",
        "~/Scripts/jquery/jquery.timeago.js",
        "~/Scripts/jquery.signalR.min.js",
        "~/Scripts/lightbox/js/lightbox.min.js",
        "~/Scripts/toolbar/jquery.toolbar.js",
        "~/Scripts/dx.all.js",
        "~/Scripts/devextreme/dx.aspnet.data.js",
        "~/Scripts/devextreme/dx.aspnet.mvc.js",
        "~/Scripts/devextreme/localisation/dx.messages.frca.js"
    ];

loaddependencies(dependencies);

I've tried many solutions before that, such as including the provider plugin to expose jquery globally:

 new webpack.ProvidePlugin({ 
        $: 'jquery', 
        jQuery: 'jquery'
      }) 

with

test: require.resolve('jquery'),
        use: [{
          loader: 'expose-loader',
          options: 'jQuery'
        },{
          loader: 'expose-loader',
          options: '$'
        }]

yet that gives me the following error: "require is not defined." (which is normal since i'm not in a Node environment). I've added also

externals: {
    jquery: 'jQuery'
  }

That didn't work. I've also tried the soluition on the following SO question (solution 3,4,5). It all failed! I've been at this for weeks and I seem to run out of solutions. What in the f*** hell do I have to do make it work?

C.O.D.E
  • 885
  • 8
  • 19
  • If you want to serve the dependencies to your client as separate files, you can do so by using the copy-webpack-plugin to copy them to your output folder. Is that what you want to do? – GTG Feb 18 '19 at 09:42
  • @GTG: Not really. What I really want to do is include all local javascript files in Webpack. Also I've look at the copy-webpack-plugin, but it's only good for assets, not for scripts. – C.O.D.E Feb 18 '19 at 14:55
  • copy-webpack-plugin works for scripts also, it basically just copies files from one place to another. Are you then looking to have the dependencies bundled together as a separate bundle? You can have more than one entry, but having a separate one with all the vendor files is discouraged. See https://webpack.js.org/concepts/entry-points/ – GTG Feb 18 '19 at 15:45
  • @GTG: I did try that with just including devextreme scripts. It bundled with success, but when I'm running the .net application, i ended up having many js errors such as "DevExpress is not defined". – C.O.D.E Feb 18 '19 at 16:33
  • That sounds like you are not importing the DevExpress scripts into your own JavaScript files. Do something like "import '../../Scripts/dx.all.js'" (there are other variants, e.g. using require). – GTG Feb 19 '19 at 09:45
  • I'm a little confused about you saying that you are not running this on a Node server. With webpack, the server you serve the app from doesn't matter right? Webpack runs and creates one or more bundles, which are Javascript files that the user's browser can understand. So the hosting environment doesn't matter so much. To help with troubleshooting I would look at the bundle that is being built and ensure that you have minification and uglify disabled in your webpack config. You shouldn't need dependencies.js if you're using webpack properly since it'll bundle those together for you. – arjabbar Feb 21 '19 at 14:34
  • @arjabbar: What I'm trying to include right now are amd modules (all in js files), but i'm still having trouble. – C.O.D.E Feb 21 '19 at 15:19

1 Answers1

0

Well, after many weeks of playing in Webpack, I finally managed to find a solution.

Basically I had to break it down into 4 typescript files; each containing all the necessary local js scripts to be imported. On one file which contains only jQuery, i had to do the following:

import "expose-loader?$!jquery";
import "expose-loader?jQuery!jquery";

Then all the other typescript files contains import statements for local js files.

My webpack.config.js file looks like the following:

const webpack = require('webpack');
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

const mainScripts = {
    mode: 'development',
    entry: path.resolve('./Scripts/tsScripts/main.ts'),
    devtool: "source-map",
    output: {
        filename: 'mainScripts .js',
        path: path.resolve(__dirname, './dist/scripts')
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"]
    },
    module: {
        rules:
        [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.tsx?$/,
                use: 'ts-loader'
            },
            {
                parser: {
                    amd: false
                }
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(['./dist'])
    ],
    optimization: {
        minimize: true,
        minimizer: [new UglifyJsPlugin({
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
        })]
    },
};

const scriptDependencies = {
    mode: 'development',
    entry: path.resolve('./Scripts/tsScripts/dependencies.ts'),
    output: {
        filename: 'scriptDependencies.js',
        path: path.resolve(__dirname, './dist/scripts')
    },
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            Globalize$: path.resolve(__dirname, "Scripts/globalize/globalize.js"),
            Globalize: path.resolve(__dirname, "Scripts/globalize/globalize"),
            cldr$: path.resolve(__dirname, "Scripts/cldr/cldr.js"),
            cldr: path.resolve(__dirname, "Scripts/cldr/cldr")
        }
    },
    module:
    {
        rules:
            [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.tsx?$/,
                    use: 'ts-loader'
                },
                {
                    test: require.resolve('globalize'),
                    use: [{
                        loader: 'expose-loader',
                        options: 'Globalize'
                    }]
                },
                {
                    parser: {
                        amd: false
                    }
                }
            ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            Globalize: 'Globalize'
        })
    ],
    optimization: {
        minimize: true,
        minimizer: [new UglifyJsPlugin({
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
        })]
    },
};

const scriptDevExt = {
    mode: 'development',
    entry: path.resolve('./Scripts/tsScripts/devext.ts'),
    output: {
        filename: 'scriptDevExt.js',
        path: path.resolve(__dirname, './dist/scripts')
    },
    resolve: {
        extensions: ['.js'],
    },
    module:
    {
        rules:
        [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                parser: {
                    amd: false
                }
            }
        ]
    },
    optimization: {
        minimize: true,
        minimizer: [new UglifyJsPlugin({
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
        })]
    },
};


const jqueryDep= {
    mode: 'development',
    entry: path.resolve('./Scripts/tsScripts/jqueryDependency.ts'),
    output: {
        filename: 'jqueryDep.js',
        path: path.resolve(__dirname, './dist/scripts')
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"],
        alias: {
            jquery: path.resolve('./Scripts/jquery/jquery.min.js')
        }
    },
    module: {
        rules:
            [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.tsx?$/,
                    use: 'ts-loader'
                },
                {
                    test: require.resolve('jquery'),
                    use: [{
                        loader: 'expose-loader',
                        options: 'jQuery'
                    }, {
                        loader: 'expose-loader',
                        options: '$'
                    }]
                },
                {
                    parser: {
                        amd: false
                    }
                }
            ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            "window.jQuery": 'jquery'
        })
    ],
    optimization: {
        minimize: true,
        minimizer: [new UglifyJsPlugin({
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
        })]
    },
};

module.exports = [jqueryDep, scriptDependencies, scriptDevExt , mainScripts ];

It's finally working correctly.

C.O.D.E
  • 885
  • 8
  • 19