是否可以用 webpack 定义一个全局变量来产生这样的结果:
var myvar = {};
我看到的所有示例都使用外部文件 require("imports?$=jquery!./file.js")
是否可以用 webpack 定义一个全局变量来产生这样的结果:
var myvar = {};
我看到的所有示例都使用外部文件 require("imports?$=jquery!./file.js")
有几种方法可以处理全局变量:
Webpack 只对module进行一次评估,因此您的实例保持全局并在module之间进行更改。因此,如果您创建类似 a 的内容globals.js
并导出所有全局变量的对象,那么您可以import './globals'
读取/写入这些全局变量。您可以导入一个module,从一个函数更改对象,然后导入另一个module并读取函数中的这些更改。还要记住事情发生的顺序。Webpack 将首先获取所有导入并按顺序加载它们entry.js
。然后它会执行entry.js
。所以你在哪里读/写全局变量很重要。它是来自module的根范围还是在稍后调用的函数中?
配置文件
export default {
FOO: 'bar'
}
一些文件.js
import CONFIG from './config.js'
console.log(`FOO: ${CONFIG.FOO}`)
注意:如果您希望new
每次都有实例,请使用ES6 类。传统上,在 JS 中,您会大写类(而不是小写的对象),例如
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()
以下是如何使用 Webpack 的 ProvidePlugin(它使module可用作每个module中的变量,并且仅在您实际使用它的那些module中可用)。当您不想import Bar from 'foo'
一次又一次地输入时,这很有用。或者,您可以在此处引入像 jQuery 或 lodash 这样的全局包(尽管您可能会查看 Webpack 的Externals)。
步骤 1) 创建任何module。例如,一组全局实用程序会很方便:
实用程序.js
export function sayHello () {
console.log('hello')
}
步骤 2) 为module添加别名并添加到 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'
})
]
}
现在只需调用utils.sayHello()
任何 js 文件,它应该可以工作。如果您在 Webpack 中使用它,请确保重新启动您的开发服务器。
注意:不要忘记告诉你的 linter 关于全局,这样它就不会抱怨。例如,请在此处查看我对 ESLint 的回答。
如果您只想将 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");
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/
你会看到这通常用于 polyfills,例如: window.Promise = Bluebird
(对于服务器端项目) dotenv 包将采用本地配置文件(如果有任何密钥/凭据,您可以将其添加到 .gitignore 中)并将您的配置变量添加到 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 的Externals,如果你想从你的构建包中排除一些module,请使用它。Webpack 将使module全局可用,但不会将其放入您的包中。这对于像 jQuery 这样的大型库很方便(因为摇树外部包在 Webpack 中不起作用),在这些库中,您已经在单独的脚本标签(可能来自 CDN)中将这些加载到页面上。
我正要问同样的问题。进一步搜索了一下,decyphering的WebPack的文档的一部分之后,我认为,你想要什么output.library
,并output.libraryTarget
在在webpack.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'
...
}
现在,如果您将生成的www/js/index.js
文件链接到html 脚本标记中,您可以myLibrary.foo
从其他脚本中的任何位置访问。
使用定义插件。
DefinePlugin 允许您创建可以在编译时配置的全局常量。
new webpack.DefinePlugin(definitions)
plugins: [
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true)
})
//...
]
console.log(`Environment is in production: ${PRODUCTION}`);
您可以使用定义window.myvar = {}
。当你想使用它时,你可以使用 likewindow.myvar = 1
我通过将全局变量设置为与它们最相关的类的静态属性来解决这个问题。在 ES5 中,它看起来像这样:
var Foo = function(){...};
Foo.globalVar = {};