公开通过webpack捆绑的javascript全局变量

时间:2017-06-23 15:02:33

标签: javascript webpack bundle frontend

问题

我觉得这应该比现在更直接。我需要从前端访问我的所有javascript库,因为我将它集成到旧系统中,我无法从前端调用require("bundle.js");。必须可以从前端页面的全局范围访问捆绑文件的全局范围内的 Everything ,并通过<script>标记导入它们。

所以我需要改变旧的:

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

到新的:

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

我尝试过的事情

  1. expose-loader:如果我没有100个全局变量,我不想明确告诉它看起来完全有效 对

  2. ProvidePlugin:只有真正让图书馆看到其他图书馆。我也无法用我当前的设置显式写出我需要的所有全局变量(不断添加更多)。

  3. 我需要什么

    因此,为了更清晰,我需要webpack.config.js看起来像这些选项之一:

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

    或者:

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

    我错了吗?

    我缺少一个明显的解决方案吗?

    铊;博士: 如何通过<script src="js/bundle.js"></script>在前端html页面上导入时,如何从我的捆绑js文件中创建全局变量?

    顺便说一下:如果有人是网络传奇人物并且知道为什么这是一个糟糕的方法,请在下面发布简短的解释,以便我可以解决我的生活。

5 个答案:

答案 0 :(得分:9)

这是我在自己的网站上如何做的一个例子。我不确定这是唯一的方式,甚至是最好的方式,但它干净,简单,对我有用。

重要的注意事项 - 在窗口上声明事物时使用window["propName"],因为当您运行webpack -p时,它会解释所有非字符串,因此如果您将其定义为{ {1}},它可以更改为window.propName,而其余代码不知道它是什么。使用括号表示法将其声明为字符串将强制webpack保持名称完整,以便您可以从具有相同名称的任何位置访问它。

site.ts (可以是.js,无关紧要)

s.c

Layout.html (每页都加载)

/*************************/
/*** 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");

<强> webpack.config.js

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

答案 1 :(得分:2)

注意:这不是理想的情况,但因为我添加了一定量的新全局变量,我需要制作一个插件来为我捆绑我的javascript。

webpack-raw-bundler

这只是将您的代码堆叠在一起以包含在前端中。这是我的用法示例:

用法

来自旧的:

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

到新的:

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

安装到配置

  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'
             ]
       })
    ]
 }

公平警告:

这不应该是您的首选解决方案 ,但我遇到了一个错误的案例,这使得这个问题变得最简单。使用expose-loaderimportwindow['module'] = require('module.js')会更加安全,因为这就是构建webpack的原因。然而,如果您有一些令人头疼的问题并且只想要一个简单的捆绑包,请感觉免费使用此插件。

答案 2 :(得分:0)

如果您使用的是webpack 2.x,则有一个内置插件

您可以定义全局变量,然后可以访问它。

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

这是我的完整配置

&#13;
&#13;
    
    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'
            })
        ]
    };
&#13;
&#13;
&#13;

这是我的输入文件

&#13;
&#13;
/********************
 *   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";
&#13;
&#13;
&#13;

答案 3 :(得分:0)

我遇到了同样的问题,我发现最好的解决方案是使用 webpack-concat-plugin

它的作用:

  • 将所有内容整合到一个文件
  • 允许我指定生成的文件名,包括执行缓存清除的[缓存]模板
  • 通过HtmlWebpackPlugin将自身添加到生成的html

唯一不做的就是不将所有全局变量泄漏到全局范围。

答案 4 :(得分:0)

听起来OP所寻找的是exports-loader而不是expose-loader

要公开模块,请使用expose-loader

要公开全局变量,请使用exports-loader

这是明确记录了答案的交易之一,但是您必须首先知道要寻找的东西并知道其名称。这两个相似的加载器也被赋予了相似的名称,这无济于事。