Javascript 使用 webpack 定义全局变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37656592/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:35:06  来源:igfitidea点击:

Define global variable with webpack

javascriptwebpackwebpack-2webpack-3

提问by Teneff

Is it possible to define a global variable with webpack to result something like this:

是否可以用 webpack 定义一个全局变量来产生这样的结果:

var myvar = {};

All of the examples I saw were using external file require("imports?$=jquery!./file.js")

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

回答by prograhammer

There are several way to approach globals:

有几种方法可以处理全局变量:

1) Put your variables in a module.

1)把你的变量放在一个模块中。

Webpack evaluates modules only once, so your instance remains global and carries changes through from module to module.So if you create something like a globals.jsand export an object of all your globals then you can import './globals'and read/write to these globals. You can import into one module, make changes to the object from a function and import into another module and read those changes in a function. Also remember the order things happen. Webpack will first take all the imports and load them up in order starting in your entry.js. Then it will execute entry.js. So where you read/write to globals is important. Is it from the root scope of a module or in a function called later?

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

Note: If you want the instance to be neweach time, then use an ES6 class. Traditionally in JS you would capitalize classes (as opposed to the lowercase for objects) like
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()

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

2) Webpack's ProvidePlugin

2)的WebPack的ProvidePlugin

Here's how you can do it using Webpack's ProvidePlugin (which makes a module available as a variable in every module and only those modules where you actually use it). This is useful when you don't want to keep typing import Bar from 'foo'again and again. Or you can bring in a package like jQuery or lodash as global here (although you might take a look at Webpack's Externals).

以下是如何使用 Webpack 的 ProvidePlugin(它使模块可用作每个模块中的变量,并且仅在您实际使用它的那些模块中可用)。当您不想import Bar from 'foo'一次又一次地输入时,这很有用。或者,您可以在此处引入像 jQuery 或 lodash 这样的全局包(尽管您可能会查看 Webpack 的Externals)。

Step 1) Create any module. For example, a global set of utilities would be handy:

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

utils.js

实用程序.js

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

Step 2) Alias the module and add to ProvidePlugin:

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

webpack.config.js

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

}

Now just call utils.sayHello()in any js file and it should work. Make sure you restart your dev-server if you are using that with Webpack.

现在只需调用utils.sayHello()任何 js 文件,它应该可以工作。如果您在 Webpack 中使用它,请确保重新启动您的开发服务器。

Note: Don't forget to tell your linter about the global, so it won't complain. For example, see my answer for ESLint here.

注意:不要忘记告诉你的 linter 关于全局,所以它不会抱怨。例如,请在此处查看我对 ESLint 的回答

3) Use Webpack's DefinePlugin

3)使用Webpack的DefinePlugin

If you just want to use const with string values for your globals, then you can add this plugin to your list of Webpack plugins:

如果您只想将 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")
})

Use it like:

像这样使用它:

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

4) Use the global window object (or Node's global)

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/

You'll see this commonly used for polyfills, for example: window.Promise = Bluebird

你会看到这通常用于 polyfills,例如: window.Promise = Bluebird

5) Use a package like dotenv

5) 使用像dotenv这样的包

(For server side projects) The dotenv package will take a local configuration file (which you could add to your .gitignore if there are any keys/credentials) and adds your configuration variables to Node's process.envobject.

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

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

Create a .envfile in the root directory of your project. Add environment-specific variables on new lines in the form of NAME=VALUE. For example:

.env在项目的根目录中创建一个文件。在新行中以NAME=VALUE. 例如:

DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3

That's it.

就是这样。

process.envnow has the keys and values you defined in your .envfile.

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

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

Notes:

笔记:

Regarding Webpack's Externals, use it if you want to exclude some modules from being included in your built bundle. Webpack will make the module globally available but won't put it in your bundle. This is handy for big libraries like jQuery (because tree shaking external packages doesn't work in Webpack) where you have these loaded on your page already in separate script tags (perhaps from a CDN).

关于 Webpack 的Externals,如果您想从构建的包中排除某些模块,请使用它。Webpack 将使模块全局可用,但不会将其放入您的包中。这对于像 jQuery 这样的大型库很方便(因为摇树外部包在 Webpack 中不起作用),在这些库中,您已经在单独的脚本标签(可能来自 CDN)中将这些加载到页面上。

回答by OriolBG

I was about to ask the very same question. After searching a bit further and decyphering part of webpack's documentation I think that what you want is the output.libraryand output.libraryTargetin the webpack.config.jsfile.

我正要问同样的问题。进一步搜索了一下,decyphering的WebPack的文档的一部分之后,我认为,你想要什么output.library,并output.libraryTarget在在webpack.config.js文件中。

For example:

例如:

js/index.js:

js/index.js:

var foo = 3;
var bar = true;

webpack.config.js

webpack.config.js

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

Now if you link the generated www/js/index.jsfile in a html script tag you can access to myLibrary.foofrom anywhere in your other scripts.

现在,如果您www/js/index.js在 html 脚本标签中链接生成的文件,您可以myLibrary.foo从其他脚本中的任何位置访问。

回答by Ricky

Use DefinePlugin.

使用定义插件

The DefinePlugin allows you to create global constants which can be configured at compile time.

DefinePlugin 允许您创建可以在编译时配置的全局常量。

new webpack.DefinePlugin(definitions)

Example:

例子:

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

Usage:

用法:

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

回答by Anh Nguyen

You can use define window.myvar = {}. When you want to use it, you can use like window.myvar = 1

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

回答by pasx

I solved this issue by setting the global variables as a static properties on the classes to which they are most relevant. In ES5 it looks like this:

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

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