用 webpack 定义全局变量

有没有可能用 webpack 定义一个全局变量,结果如下:

var myvar = {};

我看到的所有示例都使用外部文件 require("imports?$=jquery!./file.js")

239389 次浏览

您可以使用定义 window.myvar = {}。 当您想使用它时,您可以像使用 window.myvar = 1一样使用它

我正要问同样的问题。在进一步搜索并破译了 webpack 的部分文档之后,我认为您需要的是 webpack.config.js文件中的 output.libraryoutput.libraryTarget

例如:

Js/index.js:

var foo = 3;
var bar = true;

Webpack.config.js

module.exports = {
...
entry: './js/index.js',
output: {
path: './www/js/',
filename: 'index.js',
library: 'myLibrary',
libraryTarget: 'var'
...
}

现在,如果在 html 脚本标记中链接生成的 www/js/index.js文件,就可以从其他脚本中的任何地方访问 myLibrary.foo

接近全球化有几种方式:


把你的变量放在一个模块里。

Webpack 只计算模块一次,因此您的实例仍然是全局的,并在模块之间进行更改。所以如果你创建一个类似于 globals.js的东西并导出所有全局对象,那么你可以 import './globals'并读/写这些全局对象。您可以导入到一个模块中,从函数中对对象进行更改,然后导入到另一个模块中,并读取函数中的这些更改。还要记住事情发生的顺序。Webpack 将首先获取所有导入,并按照从 entry.js开始的顺序加载它们。然后执行 entry.js。所以对全局变量进行读写操作很重要。它是来自模块的根作用域还是稍后调用的函数?

Config.js

export default {
FOO: 'bar'
}

一些文件

import CONFIG from './config.js'
console.log(`FOO: ${CONFIG.FOO}`)

注意 : 如果希望每次实例都是 new,那么使用 ES6课程。传统上,在 JS 中,类的大写形式(与对象的小写形式相反)如下
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()


2. 使用 Webpack 的 提供插件

下面介绍如何使用 Webpack 的 ProvidePlugin (它使模块在每个模块中都可以作为变量使用,而且只能在您实际使用它的模块中使用)。当您不想一遍又一遍地键入 import Bar from 'foo'时,这非常有用。或者,您可以在这里引入一个像 jQuery 或 loash 这样的包作为 global (尽管您可以查看 Webpack 的 外在的)。

创建任何模块。例如,一组全局的实用程序会很方便:

Utils.js

export function sayHello () {
console.log('hello')
}

第二步: 使模块别名化,并添加到供应插件:

Webpack.config.js

var webpack = require("webpack");
var path = require("path");


// ...


module.exports = {


// ...


resolve: {
extensions: ['', '.js'],
alias: {
'utils': path.resolve(__dirname, './utils')  // <-- When you build or restart dev-server, you'll get an error if the path to your utils.js file is incorrect.
}
},


plugins: [


// ...


new webpack.ProvidePlugin({
'utils': 'utils'
})
]


}

现在只需在任何 js 文件中调用 utils.sayHello(),它就应该可以工作了。如果在 Webpack 中使用 dev-server,请确保重新启动它。

注意: 不要忘记告诉你的线程关于全局,这样它就不会抱怨。例如,看我的 这里是 ESLint 的答案


3. 使用 Webpack 的 定义插件

如果你只是想为你的全局变量使用 const 和字符串值,那么你可以把这个插件添加到你的 Webpack 插件列表中:

new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify("5fa3b9"),
BROWSER_SUPPORTS_HTML5: true,
TWO: "1+1",
"typeof window": JSON.stringify("object")
})

像这样使用:

console.log("Running App version " + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");

4. 使用全局窗口对象(或 Node 的全局对象)。

window.foo = 'bar'  // For SPA's, browser environment.
global.foo = 'bar'  // Webpack will automatically convert this to window if your project is targeted for web (default), read more here: https://webpack.js.org/configuration/node/

您将看到这通常用于填充,例如: window.Promise = Bluebird


5. 使用像 Dotenv这样的软件包。

(对于服务器端项目) dotenv 包将采用本地配置文件(您可以将其添加到。(如果有任何键/凭据,就忽略它) ,并将您的配置变量添加到 Node 的 Process.env对象。

// As early as possible in your application, require and configure dotenv.
require('dotenv').config()

在项目的根目录中创建一个 .env文件。以 NAME=VALUE的形式在新行上添加特定于环境的变量。例如:

DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3

就是这样。

process.env现在具有在 .env文件中定义的键和值。

var db = require('db')
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
})

笔记

关于 Webpack 的 外在的,如果您希望从构建的包中排除一些模块,可以使用它。Webpack 将使模块在全球范围内可用,但不会将其放入包中。这对于像 jQuery 这样的大型库来说非常方便(因为它会动摇外部包 在 Webpack 行不通) ,在这些库中,页面上已经以单独的脚本标记(可能来自 CDN)加载了这些内容。

使用 < strong > DefePlugin

DefePlugin 允许您创建全局常量,这些常量可以是 在编译时配置。

new webpack.DefinePlugin(definitions)

例如:

plugins: [
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true)
})
//...
]

用法:

console.log(`Environment is in production: ${PRODUCTION}`);

我通过将全局变量设置为与它们最相关的类的静态属性来解决这个问题。在 ES5中,它是这样的:

var Foo = function(){...};
Foo.globalVar = {};

DefePlugin 实际上没有定义任何东西。它所做的是替换包代码中存在的变量。如果该变量不存在于您的代码中,它将什么也不做。所以它不会创建全局变量。

要创建一个全局变量,请在代码中编写它:

window.MyGlobal = MY_GLOBAL;

并使用 Definition ePlugin 将 MY_GLOBAL替换为一些代码:

new webpack.DefinePlugin({
'MY_GLOBAL': `'foo'`,
// or
'MY_GLOBAL': `Math.random()`,
}),

然后您的输出 JS 将如下所示:

window.MyGlobal = 'foo';
// or
window.MyGlobal = Math.random();

但是 MY_GLOBAL在运行时实际上永远不会存在,因为它从来没有被定义过。这就是为什么 Definition Plugin 有一个误导性的名字。

在某个旧项目中尝试绑定 < script > tag js 文件时,可能会遇到这个问题。 不要为此使用 webpack,如果加入50多个类似 jquery 的库,然后计算出所有的全局变量,或者它们使用嵌套要求,这可能是不可能的。我建议直接使用 uglify js,这样可以在两个命令中解决所有这些问题。

npm install uglify-js -g


uglifyjs --compress --mangle --output bundle.js -- js/jquery.js js/silly.js