Set javascript globals bundled via webpack

Problem

I feel it should be simpler than that. I need to access all my javascript libraries from the interface, and since I integrate it into the old system, I cannot call require("bundle.js"); from the frontend. Everything in the global area of โ€‹โ€‹the merged files should be accessible from the global area of โ€‹โ€‹the interface page, importing them via the <script> .

So I need to change the old one:

 <script src="js/jquery.js"></script> <script src="js/silly.js"></script> <script> $(silly()); // Some function in silly.js global scope </script> 

To the new:

 <script src="js/bundle.js"></script> <script> $(silly()); // Some function in silly.js global scope </script> 

Things i tried

  • expose-loader: This will work if I did not have 100 global variables that I do not want to explicitly specify for.

  • ProvidePlugin: Only allows libraries to see other libraries. I also cannot explicitly write all the global variables that I need, with my current setting (all are added constantly).

What I need

So, for clarity, I need my webpack.config.js look like one of the following options:

 // Everything is wrapped in module.exports and other irrelevant things plugins: [ new StaticLibraryMergerSuperNeatPlugin("js/*.js") ] // ... 

Or:

 rules: [ { test: /\.js$/, use: [ "neat-merging-cool-loader", "babel-loader"] } ] // ... 

Am I really not mistaken about this?

Is there an obvious solution that I am missing?

T; D: How to make global variables from my linked js files, be exposed to the global scope when importing to the frontend html page via <script src="js/bundle.js"></script> ?

Btw: If someone is a webpack legend and knows why this is a bad approach, write a short explanation below so that I can fix my life.

+5
source share
4 answers

Note. This is not an ideal scenario, but since I have a constant number of added global additives, I needed to make a plugin to link my javascript for me.

webpack-raw-bundler

It just puts your code together for inclusion in the interface. Here is my usage example:

Using

From the old:

 <script src="js/jquery.js"></script> <script src="js/silly.js"></script> <script> $(silly()); // Some function in silly.js global scope </script> 

To the new:

 <script src="js/bundle.js"></script> <script> $(silly()); // Some function in silly.js global scope </script> 

Installation in configuration

  var RawBundlerPlugin = require('webpack-raw-bundler'); module.exports = { plugins: [ new RawBundlerPlugin({ excludedFilenames: [/angulartics/], readEncoding: "utf-8", includeFilePathComments: false, bundles: [ "vendor.js", "styles.css" ], "vendor.js": [ 'js/*.js' ], "styles.css": [ 'css/bootstrap.css', 'css/edits.css' ] }) ] } 

Fair warning:

This should not be your decision, but I had a bad case that made this the easiest option. Using expose-loader and import or window['module'] = require('module.js') much safer since it was a website. However, if you have some headaches and you just want a simple kit, feel free to use this plugin.

+1
source

Here is an example of how I do this on my own site. I'm not sure if this is the only way or even the best way, but it is clean, simple and works for me.

Important noteworthy note . Use window["propName"] when declaring objects in a window, because when you run webpack -p it will carbonize any non-line lines, so if you define it as window.propName , it can be changed to something like sc , and the rest of your code does not know what it is. Declaring a character as a string as a string will cause webpack to keep the name intact so that you can access it from anywhere with the same name.

site.ts (maybe .js, doesn't matter)

 /*************************/ /*** JQUERY + JQUERYUI ***/ /*************************/ /* var declaration for typescript - not needed if not using .ts */ declare var $:JQueryStatic; declare var jQuery:JQueryStatic; window["$"] = window["jQuery"] = require("jquery"); require("jquery-ui/effects/effect-slide"); require("jquery-ui/widgets/autocomplete"); require("jquery-ui/widgets/button"); require("jquery-ui/widgets/datepicker"); require("jquery-ui/widgets/tooltip"); /*************************/ /* END JQUERY + JQUERYUI */ /*************************/ /***************/ /*** ANGULAR ***/ /***************/ /* var declaration for typescript - not needed if not using .ts */ declare var angular:ng.IAngularStatic; window["angular"] = require("angular"); require("angular-sanitize"); /***************/ /* END ANGULAR */ /***************/ /************************/ /*** MISC THIRD-PARTY ***/ /************************/ window["moment"] = require("moment"); window["saveAs"] = require("FileSaver").saveAs; window["JSZip"] = require("jszip"); /************************/ /* END MISC THIRD-PARTY */ /************************/ /* var declaration for typescript - not needed if not using .ts */ declare var globals:Globals; window["globals"] = require("./globals"); 

Layout.html (loaded on every page)

 ..... <script src="/dist/scripts/site.bundle.js"></script> ..... 

webpack.config.js

 var path = require('path'); var resolve = path.resolve; var AssetsPlugin = require('assets-webpack-plugin'); var WebpackCleanupPlugin = require("webpack-cleanup-plugin"); 'use strict'; var babelOptions = { "presets": [ [ "es2015", { "modules": false } ], "es2016" ] }; module.exports = [{ cache: true, context: resolve('Scripts'), devtool: "source-map", entry: { site: './site.ts', }, output: { path: path.resolve(__dirname, './dist/scripts'), filename: '[name].bundle.js', }, module: { rules: [{ test: /\.ts$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: babelOptions }, { loader: 'ts-loader' } ] }, { test: /\.js$/, exclude: /node_modules/, use: [ { loader: 'babel-loader', options: babelOptions } ] }] }, plugins: [ new AssetsPlugin({ path: path.resolve(__dirname, './dist/assets') }), new WebpackCleanupPlugin({}) ], }]; 
+4
source

If you are using webpack 2.x, there is a built-in plugin

You define a global variable, and then you can get it.

  plugins: [ new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", "window.Tether": 'tether', "Tether": 'tether' }), ... ] 

here is my complete configuration

 var webpack = require("webpack"); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var path = require("path") module.exports = { entry: "./src/entry-js.js", devtool: 'source-map', output: { path: path.join(__dirname, "/public/dist/js"), publicPath: "/public/", filename: 'bundle.js', chunkFilename: 'chunk.[name].[id].js', }, module: { rules: [ { test: /\.js$/, loader: "babel-loader", options: { presets: ["es2015", "stage-0"] }, exclude: [ path.resolve(__dirname, "node_modules") ], }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }, { test: /\.(scss|sass)$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ "css-loader", "sass-loader" ] }) }, { test: /\.less$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [ "css-loader", "less-loader" ] }) }, { test: /\.(png|svg|jpg|gif)$/, use: [{ loader:"file-loader", options: { limit: 500, name: "../img/[name].[ext]" } }] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [{ loader:"file-loader", options: { limit: 500, name: "../fonts/[name].[ext]" } }] } ] }, plugins: [ new ExtractTextPlugin({ filename: "../css/bundle.css", disable: false, allChunks: true }), new webpack.ProvidePlugin({ $: "jquery", jQuery: "jquery", "window.jQuery": "jquery", "window.Tether": 'tether', "Tether": 'tether' }) ] }; 

Here is my recording file

 /******************** * CSS Libraries * ********************/ // normalize v7 import "../node_modules/normalize.css/normalize.css"; // bootstrap v4.alpha-5 import "../node_modules/bootstrap/scss/bootstrap.scss"; /****************** * CSS Custom * ******************/ import "./css/main.css"; import "./sass/main.scss"; /******************** * JS Libraries * ********************/ //Jquery v3.2.1 import '../node_modules/jquery/src/jquery.js'; import Tether from 'tether'; //Bootstrap v4-alpha-5 import "../node_modules/bootstrap/dist/js/bootstrap.min.js"; import "./js/main.js"; 
0
source

I had the same problem and the best solution I found was to use webpack-concat-plugin .

What does he do:

  • Same as single file.
  • Lets me specify the resulting file name, including [cache] template, to disable caching
  • Adds itself via HtmlWebpackPlugin to the resulting html

The only thing he does not do is not leak all global variables into the global scope.

0
source

Source: https://habr.com/ru/post/1269162/


All Articles