Определите глобальную переменную с помощью веб-пакета

Можно ли определить глобальную переменную с помощью веб-пакета, чтобы получить что-то вроде этого:

var myvar = {};

Все примеры, которые я видел, использовали внешний файл require("imports?$=jquery!./file.js")

8 ответов

Решение

Есть несколько способов приблизиться к глобалам:

1) Поместите ваши переменные в модуль.

Webpack оценивает модули только один раз, поэтому ваш экземпляр остается глобальным и передает изменения от модуля к модулю. Так что если вы создаете что-то вроде globals.js и экспортировать объект всех ваших глобалов, то вы можете import './globals' и читать / писать в эти глобалы. Вы можете импортировать в один модуль, вносить изменения в объект из функции, импортировать в другой модуль и считывать эти изменения в функции. Также запомните порядок вещей. Сначала Webpack выполнит все операции импорта и загрузит их в порядке, начиная с вашего entry.js, Тогда он выполнит entry.js, Поэтому, где вы читаете / пишете глобальные переменные, важно. Это из корневой области модуля или из функции, вызываемой позже?

Примечание: если вы хотите, чтобы экземпляр был new каждый раз, затем используйте класс ES6. Традиционно в JS вы должны использовать классы (в отличие от строчных букв для объектов), например
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()

2) веб-пакет ProvidePlugin

Вот как вы можете сделать это, используя ProvidePlugin Webpack (который делает модуль доступным в качестве переменной в каждом модуле и только в тех модулях, где вы его фактически используете). Это полезно, когда вы не хотите продолжать печатать import Bar from 'foo' опять и опять. Или вы можете использовать пакет как jQuery или lodash как глобальный (хотя вы можете взглянуть на внешние компоненты Webpack).

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

}

Теперь просто позвоните utils.sayHello() в любом файле JS, и это должно работать. Убедитесь, что вы перезапускаете свой dev-сервер, если используете его с Webpack.

Примечание: не забудьте рассказать своему линтеру о глобальном, чтобы он не жаловался. Например, см. Мой ответ для ESLint здесь.

3) Используйте DefinePlugin 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) Используйте глобальный объект окна (или глобальный узел)

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, если есть какие-либо ключи / учетные данные) и добавит ваши переменные конфигурации в объект 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).

Я собирался задать тот же вопрос. Пройдя немного дальше и расшифровав часть документации веб-пакета, я думаю, что вам нужно 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.

DefinePlugin позволяет вам создавать глобальные константы, которые можно настроить во время компиляции.

new webpack.DefinePlugin(definitions)

Пример:

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

Использование:

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

Вы можете использовать определить window.myvar = {}, Когда вы хотите использовать его, вы можете использовать как window.myvar = 1

Вы можете столкнуться с этой проблемой при попытке связать js-файлы тега <script> в каком-то старом проекте. Не используйте для этого веб-пакет, это может быть даже невозможно, если вы присоединитесь к более чем 50 библиотекам, таким как jquery, а затем выясните все глобальные переменные или если они использовали вложенные требования. Я бы посоветовал просто использовать вместо этого uglify js, который устраняет все эти проблемы в 2 командах.

      npm install uglify-js -g

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

DefinePlugin на самом деле ничего не определяет. Что он делает, так это заменяет переменные, которые существуют в вашем коде пакета. Если переменная не существует в вашем коде, она ничего не сделает. Таким образом, он не создает глобальных переменных.

Чтобы создать глобальную переменную, напишите ее в своем коде:

      window.MyGlobal = MY_GLOBAL; 

И используйте DefinePlugin для замены некоторым кодом:

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

Тогда ваш выходной JS будет таким:

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

Но MY_GLOBALна самом деле никогда не будет существовать во время выполнения, потому что он никогда не определяется. Вот почему DefinePlugin имеет вводящее в заблуждение название.

Я решил эту проблему, установив глобальные переменные в качестве статических свойств для классов, для которых они наиболее актуальны. В ES5 это выглядит так:

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

2023 Решение

Чтобы добавить глобальную переменную в проект на основе веб-пакета, вы можете использовать плагин. Этот плагин позволяет вам определять глобальные константы, которые будут доступны во время компиляции. Вот пример того, как настроить глобальную переменную, используяwebpack.DefinePlugin:

вебпак.config.js

      const webpack = require('webpack');

module.exports = {
  // Your other webpack configuration
  plugins: [
    new webpack.DefinePlugin({
      GOOGLE_MAP_KEY: "google_map_keyword",
    }),
  ],
};

Чтобы получить доступ к этой переменной в вашем проекте React, вы можете использоватьprocess.env:

      // Inside your component
const googleMapKeyword = process.env.GOOGLE_MAP_KEY;
console.log(googleMapKeyword); // 'google_map_keyword'
Другие вопросы по тегам