使用webpack定义全局variables
是否有可能用webpack定义一个全局variables来得到如下结果:
var myvar = {};
我看到的所有示例都使用外部文件require("imports?$=jquery!./file.js")
有几种方式来处理全局:
1)把你的variables放在一个模块中。
Webpack只对模块进行一次评估,因此您的实例仍然是全局的,并且可以在模块之间进行更改。 所以,如果你创build一个像globals.js
一样的globals.js
并导出所有全局variables的对象,那么你可以import './globals'
并读写这些全局variables。 您可以导入到一个模块中,从一个函数中更改该对象并导入到另一个模块中,并读取函数中的这些更改。 还记得事情发生的顺序。 Webpack将首先将所有的导入和加载顺序从你的entry.js
开始。 然后它会执行entry.js
。 所以你读/写全局variables很重要。 它是从模块的根范围还是在稍后调用的函数中?
注意 :如果您希望实例每次都是new
,则使用ES6类 。 传统上在JS中,你会大写类(而不是小写的对象)
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()
2)Webpack的ProvidePlugin
下面是如何使用Webpack的ProvidePlugin(它使模块作为每个模块中的一个variables以及实际使用它的那些模块)来实现的。 当你不想一次又一次地import Bar from 'foo'
inputimport Bar from 'foo'
时,这是很有用的。 或者你可以像jQuery或lodash一样在全球范围内引入一个包(尽pipe你可能会看看Webpack的Externals )。
步骤1)创build任何模块。 例如,一个全局的公用设施将是方便的:
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 path is incorrect. } }, plugins: [ // ... new webpack.ProvidePlugin({ 'utils': 'utils' }) ] }
现在只需在任何js文件中调用utils.sayHello()
就可以了。 确保你重启你的开发服务器,如果你正在使用Webpack。
注意:不要忘记告诉你的linter关于全球,所以它不会抱怨。 例如,请参阅我在这里的ESLint的答案 。
3)使用Webpack的DefinePlugin
如果你只是想为你的全局variables的string值使用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/
你会看到这个常用的polyfills,例如: window.Promise = Bluebird
5)使用像dotenv一样的软件包
(对于服务器端项目)dotenv软件包将采用本地configuration文件(如果有任何密钥/凭证,您可以将其添加到.gitignore中),并将configurationvariables添加到Node的process.env对象中。
// As early as possible in your application, require and configure dotenv. require('dotenv').config()
在项目的根目录中创build一个.env
文件。 以NAME=VALUE
的forms在新行中添加环境特定的variables。 例如:
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 ,如果你想排除一些模块被包含在你构build的bundle中,可以使用它。 Webpack将使模块在全球范围内可用,但不会把它放在你的包中。 这对于像jQuery或Lodash这样的大型图书馆来说是很方便的(因为摇晃外部包的树在Webpack中不起作用 )。 然后考虑研究Webpack的库方法 (其中包括在您的index.html中为全局variables使用脚本标记的选项)。
我正想问同样的问题。 进一步search了一下之后,我认为你需要的是webpack.config.js
文件output.libraryTarget
的output.library
和output.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' ... }
现在,如果将生成的www/js/index.js
文件链接到html脚本标记中,则可以从其他脚本的任何位置访问myLibrary.foo
。
使用DefinePlugin 。
DefinePlugin允许您创build可在编译时configuration的全局常量。
new webpack.DefinePlugin(definitions)
例:
plugins: [ new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true) }) //... ]
用法:
console.log(`Environment is in production: ${PRODUCTION}`);
你可以使用define window.myvar = {}
。 当你想使用它,你可以使用像window.myvar = 1