使用 webpack 定义全局变量

2022-08-30 01:46:13

是否可以使用 webpack 定义一个全局变量来生成如下结果:

var myvar = {};

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


答案 1

有几种方法可以接近全局变量:


1. 将变量放在模块中。

Webpack 只评估一次模块,因此您的实例保持全局状态,并在模块之间进行更改。因此,如果您创建类似 a 的东西并导出所有全局变量的对象,则可以读取/写入这些全局变量。您可以导入到一个模块中,从函数对对象进行更改,然后导入到另一个模块中,然后在函数中读取这些更改。还要记住事情发生的顺序。Webpack 将首先获取所有导入,并从 .然后它将执行 。因此,在哪里读取/写入全局变量非常重要。它是来自模块的根范围还是在稍后调用的函数中?globals.jsimport './globals'entry.jsentry.js

配置.js

export default {
    FOO: 'bar'
}

某个文件.js

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

注意:如果您希望实例每次都如此,请使用 ES6 类。传统上,在JS中,你会大写类(而不是对象的小写字母),比如new
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()


2. 使用 Webpack 的 ProvidePlugin

以下是使用Webpack的ProvidPlugin(它使模块在每个模块中都可以作为变量使用,并且只有那些您实际使用它的模块)来做到这一点。当您不想一次又一次地继续键入时,这很有用。或者你可以在这里引入像jQuery或lodash这样的软件包作为全局(尽管你可以看看Webpack的Externals)。import Bar from 'foo'

步骤 1.创建任何模块。例如,一组全局实用程序将很方便:

utils.js

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

步骤2.别名模块并添加到 ProvidePlugin:

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文件,它应该可以正常工作。请确保重新启动开发服务器(如果将其与 Webpack 一起使用)。utils.sayHello()

注意:别忘了告诉你的关于全球的利特尔,所以它不会抱怨。例如,请在此处查看我对 ESLint 的回答


3. 使用 Webpack 的 DefinePlugin

如果您只想将 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. 使用全局窗口对象(或节点的全局)。

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 包将采用一个本地配置文件(如果有任何密钥/凭据,可以将其添加到 .gitignore 中),并将配置变量添加到 Node 的 process.env 对象中。

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

在项目的根目录中创建一个文件。以 的形式在新行上添加特定于环境的变量。例如:.envNAME=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)中加载了这些内容。


答案 2

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

例如:

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.jsmyLibrary.foo