Непонимание переменных среды настройки Webpack

Webpack

Введение

  • В повседневной работе по фронтенд-разработке будет как минимум два набора сред сборки.
    • Набор используется во время разработки, а результаты сборки используются для локальной разработки и отладки, без сжатия кода, печати отладочной информации, включая файлы исходной карты и т. д.
    • Набор используется при публикации, а результаты сборки используются онлайн, то есть код сжимается, во время выполнения не печатается отладочная информация, а статические файлы не включают исходную карту и т. д.
  • Концепция режима была введена в webpack 4.0.
Опции описывать
development будуprocess.env.NODE_ENVЗначение установлено наdevelopment. включитьNamedChunksPluginа такжеNamedModulesPlugin
production будуprocess.env.NODE_ENVЗначение установлено наproduction. включитьFlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginа такжеUglifyJsPlugin

2. Различные способы различения среды разработки и производственной среды.

2.1 Использование командной строки

2.1.1 Первый метод записи

"scripts": {
    // 默认 mode 为 development
    "dev1": "webpack-dev-server",
    // 默认 mode 为 production,不过这样写,打包的时候会有警告
    "build1": "webpack",
}
  • Приведенный выше сценарий сценария,Могупройти в любом модулеprocess.env.NODE_ENVПолучить текущие переменные среды
  • Но не удается получить текущие переменные среды в среде узла (в файле конфигурации веб-пакета)
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports =  {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
    		...
};

2.1.2 Метод записи 2

"scripts": {
   "dev2": "webpack --mode=development",
   "build2": "webpack --mode=production",
}
  • а такженаписание одного, тот же результат

2.1.3 Способ записи 3

"scripts": {
   "dev3": "webpack-dev-server --env=development",
   "build3": "webpack --env=production",
}
  • Приведенный выше сценарий сценария,невозможнопройти в любом модулеprocess.env.NODE_ENVПолучить текущие переменные среды
  • Но в среде узла (в файле конфигурации веб-пакета)получить по функциитекущая переменная окружения
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// undefined
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

// 通过函数获取当前环境变量
module.exports = (env,argv) => {
  console.log('env',env);// development | production
  return {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
    		...
  }
};

2.2 Использование режима

// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development | production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('NODE_ENV',process.env.NODE_ENV);// undefined

module.exports =  {
  	mode:'development',//  development | production
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
    		...
};
  • а в 2.1правописание два, тот же результат
  • Один задается в командной строке, а другой задается в файле конфигурации веб-пакета.

2.3 Использование webpack.DefinePlugin

  • Сначала вы должны знать, что делает этот плагин: Настройкиглобальная переменная(не монтируется наwindowвыше), все модули могут читать значение этой переменной
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development
   console.log(NODE_ENV);//  production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

// 这里只是凑巧和环境变量同名了,所以才不会报错
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// undefined
console.log('NODE_ENV',NODE_ENV);// error !!!

module.exports =  {
  	mode:'development',// development | production
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
  	plugins:[
            new webpack.DefinePlugin({
           	'process.env.NODE_ENV':JSON.stringify('development'),
                'NODE_ENV':JSON.stringify('production'),
       }),
    ],
    		...
};
  • Могупройти в любом модулеprocess.env.NODE_ENVПолучить текущие переменные среды
  • Но не удается получить текущие переменные среды в среде узла (в файле конфигурации веб-пакета)

2.4 Использование плагина cross-env

  • Изначально я всегда думал, что этот плагин можно использовать для установки переменных во всех средах (среда браузера, среда узла). После тестирования выяснилось, что только настройкасреда узлаПеременные под -NODE_ENV

2.4.1 Метод записи 1

"scripts": {
 	"dev1": "cross-env NODE_ENV='production' webpack-dev-server",
        "build1": "cross-env NODE_ENV='development' webpack",
}
  • Приведенный выше сценарий сценария может быть передан в любой модуль.process.env.NODE_ENVПолучить текущие переменные среды
  • Вы можете получить текущие переменные среды в среде узла (в файле конфигурации веб-пакета)
  • Но будет проблема:Значения, полученные в среде браузера и среде узла, отличаются
//  !!!!!!
// npm run build1 
//  !!!!!!

// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports =  {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
    		...
};

2.4.2 Метод записи 2

"scripts": {
  "dev2": "cross-env NODE_ENV='development' --mode development",
  "build2": "cross-env NODE_ENV='production' --mode production",
}
  • Приведенный выше сценарий сценария может быть передан в любой модуль.process.env.NODE_ENVПолучить текущие переменные среды
  • Вы можете получить текущие переменные среды в среде узла (в файле конфигурации веб-пакета)
  • Таким образом, значение переменной среды можно прочитать в среде браузера, полагаясь наmode, прочитать значение переменной среды в среде узла, опираясь наcross-env
//  !!!!!!
// npm run build2 
//  !!!!!!

// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// production
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// production

module.exports =  {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
    		...
};

3. Непонимание

  • Я часто вижу этот вопрос в некоторых группах:cross-envа такжеwebpack.DefinePluginПри совместном использовании не может пройтиprocess.env.xxxЧтобы получить установленные переменные среды, вам нужно передатьwebpack.DefinePluginустановить внутриkeyчтобы получить.
  • Возможная причина этой проблемы: сначала установите ее в cross-envNODE_ENVпеременная, а затемDefinePluginустановить переменные окружения
"scripts": {
  "dev": "cross-env NODE_ENV='development' --mode development"
}
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// development
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports =  {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
  	plugins:[
           new webpack.DefinePlugin({
             	// 设置环境变量
               	'process.env.NODE_ENV':JSON.stringify('development'),
           }),
        ],
    		...
};
  • На этом этапе вы обнаружите, что и среда браузера, и среда узла могут получать установленные переменные, а затем вы думаете, что когда позже вы установите другие глобальные переменные, вы можете написать это так.

  • думатьcross-envа такжеDefinePluginиспользуются вместе, сам этот вид очень странный, потому что роль двух различна

    • DefinePluginРоль: установить «глобальную переменную», которую можно прочитать в среде браузера, непосредственно черезkeyЧтение, невозможно прочитать в среде узла
    • cross-envРоль: установить переменные окружения через командную строкуNODE_ENV, чтобы его можно было прочитать в среде узла, черезprocess.env.NODE_ENVчитать
    • если вDefinePluginустановить вkeyдаprocess.env.NODE_ENVПереопределит WebpackmodeЗначение переменной окружения, установленное режимом
"scripts": {
  "dev": "cross-env NODE_ENV='development' --mode development"
}
// index.js 
function getEnv() {
   console.log(process.env.NODE_ENV);// 666666
}

// webpack.config.js
const path = require('path');
const webpack = require('webpack');

console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development

module.exports =  {
  	entry:'./src/index.js',
        output: {
            filename: 'js/[name].js'
        },
  	plugins:[
           new webpack.DefinePlugin({
                // 注意:因为同名的 key,这里的值会覆盖默认的值 !!!!!!
               	'process.env.NODE_ENV':JSON.stringify('666666'),
           }),
        ],
    		...
};

4. Резюме

  • cross-envдаВ частности, используется для установки переменных среды узла.из
  • webpack.DefinePluginдаСпециально используется для установки глобальных переменных в среде браузера.(не монтируется наwindowначальство)
  • Эта статья является только моим личным пониманием, пожалуйста, дайте мне знать, если есть какие-либо ошибки, большое спасибо

5. Рекомендуемое чтение

Вы действительно понимаете жизненный цикл React?

Подробные хуки React [почти 1W слов] + бой проекта

Подробный React SSR [почти 1W слов] + 2 актуальных проекта

Реализация простого веб-пакета от 0 до 1