각도 앱을 gulp에서 webpack으로 변환하려고합니다. gulp에서 나는 gulp-preprocess를 사용하여 NODE_ENV에 따라 html 페이지의 일부 변수 (예 : 데이터베이스 이름)를 바꿉니다. 웹팩으로 비슷한 결과를 얻는 가장 좋은 방법은 무엇입니까?
각도 앱을 gulp에서 webpack으로 변환하려고합니다. gulp에서 나는 gulp-preprocess를 사용하여 NODE_ENV에 따라 html 페이지의 일부 변수 (예 : 데이터베이스 이름)를 바꿉니다. 웹팩으로 비슷한 결과를 얻는 가장 좋은 방법은 무엇입니까?
답변:
이를 달성하기위한 두 가지 기본 방법이 있습니다.
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),
이는 "있는 그대로"일치하는 항목 만 대체합니다. 그렇기 때문에 문자열이 형식으로되어 있습니다. 객체와 같은 더 복잡한 구조를 가질 수 있지만 아이디어를 얻습니다.
new webpack.EnvironmentPlugin(['NODE_ENV'])
EnvironmentPlugin
DefinePlugin
내부적으로 사용 하고 환경 값을 코드로 매핑합니다. 터서 구문.
또는 별명 모듈을 통해 구성을 사용할 수 있습니다 . 소비자 측면에서 보면 다음과 같습니다.
var config = require('config');
구성 자체는 다음과 같습니다.
resolve: {
alias: {
config: path.join(__dirname, 'config', process.env.NODE_ENV)
}
}
하자 말은 process.env.NODE_ENV
있다 development
. ./config/development.js
그때에 매핑됩니다 . 맵핑 된 모듈은 다음과 같이 구성을 내보낼 수 있습니다.
module.exports = {
testing: 'something',
...
};
JSON.stringify()
'process.env.NODE_ENV': `"${process.env.NODE_ENV || 'development'}"`
JSON.stringify('development')
은 실제로 유용하지 않을 수 있습니다. 대신 JSON.stringify(someVariable)
꽤 될 수 있습니다!
NODE_ENV
그렇게하도록 설정 해야합니다. 설정 방법은 플랫폼에 따라 다릅니다.
process.env.NODE_ENV
패턴을 사용 하고 작동합니다.
CLI 인터페이스 만 사용하려면 define
webpack 옵션을 사용하십시오 . 내 스크립트에 다음 스크립트를 추가합니다 package.json
.
"build-production": "webpack -p --define process.env.NODE_ENV='\"production\"' --progress --colors"
그래서 난 그냥 실행해야합니다 npm run build-production
.
환경 특정 변수를 설정하는 방법에 대한 몇 가지 옵션을 조사한 결과 다음과 같습니다.
현재 2 개의 웹 팩 구성이 있습니다.
webpack.production.config.js
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('production'),
'API_URL': JSON.stringify('http://localhost:8080/bands')
}
}),
webpack.config.js
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('development'),
'API_URL': JSON.stringify('http://10.10.10.10:8080/bands')
}
}),
내 코드에서는 다음과 같은 간단한 방법으로 API_URL 값을 얻습니다.
const apiUrl = process.env.API_URL;
2016 년 11 월 3 일 수정
Webpack 문서에는 https://webpack.js.org/plugins/define-plugin/#usage가 있습니다.
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify("5fa3b9"),
BROWSER_SUPPORTS_HTML5: true,
TWO: "1+1",
"typeof window": JSON.stringify("object")
})
ESLint 를 사용하면 no-undef
규칙 이있는 경우 코드에 정의되지 않은 변수를 구체적으로 허용해야합니다 . 다음 과 같이 http://eslint.org/docs/rules/no-undef :
/*global TWO*/
console.log('Running App version ' + TWO);
2017 년 9 월 7 일 수정 (Create-React-App 전용)
너무 많이 구성하지 않은 경우 Create-React-App : Create-React-App-사용자 정의 환경 변수 추가를 확인하십시오 . CRA는 Webpack을 사용합니다.
process.env
되지 않아 더 이상 환경에서 포트를 무시할 수 없습니까? process.env.PORT
undefined
변환을 수행하는 동안 사용 EnvironmentPlugin
가능한 기능을 직접 사용하여 webpack
환경 변수에 액세스 할 수 있습니다.
webpack.config.js
파일에 플러그인을 선언하면 됩니다.
var webpack = require('webpack');
module.exports = {
/* ... */
plugins = [
new webpack.EnvironmentPlugin(['NODE_ENV'])
]
};
사용하려는 환경 변수의 이름을 명시 적으로 선언해야합니다.
개인적으로 많은 답변을 추가하려면 다음을 선호합니다.
const webpack = require('webpack');
const prod = process.argv.indexOf('-p') !== -1;
module.exports = {
...
plugins: [
new webpack.DefinePlugin({
process: {
env: {
NODE_ENV: prod? `"production"`: '"development"'
}
}
}),
...
]
};
이것을 사용하면 펑키 env 변수 또는 크로스 플랫폼 문제가 없습니다 (env vars 포함). 당신이 할 일은 각각 정상 webpack
또는 webpack -p
개발 또는 생산을 실행하는 것 입니다.
참조 : Github 문제
'process.env.NODE_ENV': JSON.stringify('production')
이상을 선호하십시오 process: { env: { NODE_ENV: JSON.stringify('production') } }
. 후자를 사용하면 프로세스 개체를 덮어 쓰므로 프로세스 개체의 다른 값이 정의 될 것으로 예상되는 일부 모듈과의 호환성이 손상 될 수 있습니다.
전도인 이 작성한 위의 게시물 에 대한 나의 편집 은 승인되지 않았으므로 , 추가 정보를 게시합니다.
정의 된 버전 번호 와 같이 package.json 에서 값을 선택하고 Javascript 내의 DefinePlugin 을 통해 액세스 하려는 경우 .
{"version": "0.0.1"}
그런 다음 각각의 webpack.config 내에서 package.json을 가져오고 import 변수를 사용하여 속성에 액세스 한 다음 DefinePlugin 의 속성을 사용하십시오 .
const PACKAGE = require('../package.json');
const _version = PACKAGE.version;//Picks the version number from package.json
예를 들어 webpack.config의 특정 구성은 DefinePlugin 에 METADATA를 사용하고 있습니다.
const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, {
host: HOST,
port: PORT,
ENV: ENV,
HMR: HMR,
RELEASE_VERSION:_version//Version attribute retrieved from package.json
});
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env': {
'ENV': JSON.stringify(METADATA.ENV),
'NODE_ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'VERSION': JSON.stringify(METADATA.RELEASE_VERSION)//Setting it for the Scripts usage.
}
}),
모든 타입 스크립트 파일 내에서 액세스하십시오 :
this.versionNumber = process.env.VERSION;
가장 똑똑한 방법은 다음과 같습니다.
// webpack.config.js
plugins: [
new webpack.DefinePlugin({
VERSION: JSON.stringify(require("./package.json").version)
})
]
@ zer0chain의 답변과 유사한 또 다른 답변입니다. 그러나 한 가지 차이점이 있습니다.
webpack -p
이 충분합니다.다음과 같습니다.
--define process.env.NODE_ENV="production"
그리고 이것은
// webpack.config.js
const webpack = require('webpack');
module.exports = {
//...
plugins:[
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
};
따라서 package.json
노드 파일 에는 다음과 같은 것만 필요할 수 있습니다.
{
"name": "projectname",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"debug": "webpack -d",
"production": "webpack -p"
},
"author": "prosti",
"license": "ISC",
"dependencies": {
"webpack": "^2.2.1",
...
}
}
DefinePlugin 의 몇 가지 팁 :
DefinePlugin을 사용하면 컴파일 타임에 구성 할 수있는 전역 상수를 만들 수 있습니다. 이는 개발 빌드와 릴리스 빌드간에 다른 동작을 허용하는 데 유용 할 수 있습니다. 예를 들어, 전역 상수를 사용하여 로깅 발생 여부를 결정할 수 있습니다. 아마도 개발 빌드에서는 로깅을 수행하지만 릴리스 빌드에서는 로깅을 수행하지 않을 수 있습니다. 이것이 DefinePlugin이 촉진하는 시나리오입니다.
입력 한 내용을 확인할 수 있도록 webpack --help
Config options:
--config Path to the config file
[string] [default: webpack.config.js or webpackfile.js]
--env Enviroment passed to the config, when it is a function
Basic options:
--context The root directory for resolving entry point and stats
[string] [default: The current directory]
--entry The entry point [string]
--watch, -w Watch the filesystem for changes [boolean]
--debug Switch loaders to debug mode [boolean]
--devtool Enable devtool for better debugging experience (Example:
--devtool eval-cheap-module-source-map) [string]
-d shortcut for --debug --devtool eval-cheap-module-source-map
--output-pathinfo [boolean]
-p shortcut for --optimize-minimize --define
process.env.NODE_ENV="production"
[boolean]
--progress Print compilation progress in percentage [boolean]
많은 답변을 추가하려면 :
사용 ExtendedDefinePlugin 대신 DefinePlugin
npm install extended-define-webpack-plugin --save-dev.
ExtendedDefinePlugin은 사용하기가 훨씬 간단하고 문서화되어 있습니다 :-) 링크
DefinePlugin은 훌륭한 문서 가 없기 때문에 실제로는 ##의 #DEFINE 과 같이 작동한다고 말함으로써 도움을주고 싶습니다 .
#if (DEBUG)
Console.WriteLine("Debugging is enabled.");
#endif
따라서 DefinePlugin의 작동 방식을 이해하려면 c # #define doucmentation을 읽으십시오. 링크
다음 솔루션이 Webpack 2의 환경 변수를 설정하는 것이 가장 쉽다는 것을 알았습니다.
예를 들어 웹팩 설정이 있습니다.
var webpack = require('webpack')
let webpackConfig = (env) => { // Passing envirmonment through
// function is important here
return {
entry: {
// entries
},
output: {
// outputs
},
plugins: [
// plugins
],
module: {
// modules
},
resolve: {
// resolves
}
}
};
module.exports = webpackConfig;
웹팩에 환경 변수 추가 :
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
]
플러그인 변수를 정의하고 다음에 추가하십시오 plugins
.
new webpack.DefinePlugin({
'NODE_ENV': JSON.stringify(env.NODE_ENV || 'development')
}),
이제 webpack 명령을 실행할 때 env.NODE_ENV
인수로 전달하십시오.
webpack --env.NODE_ENV=development
// OR
webpack --env.NODE_ENV development
이제 NODE_ENV
코드의 어느 곳에서나 변수에 액세스 할 수 있습니다 .
다음은 저에게 효과적이며 json 파일을 재사용하여 환경 변수를 DRY로 유지할 수있는 방법입니다.
const webpack = require('webpack');
let config = require('./settings.json');
if (__PROD__) {
config = require('./settings-prod.json');
}
const envVars = {};
Object.keys(config).forEach((key) => {
envVars[key] = JSON.stringify(config[key]);
});
new webpack.DefinePlugin({
'process.env': envVars
}),
나는 열렬한 팬이 아닙니다 ...
new webpack.DefinePlugin({
'process.env': envVars
}),
... 어떤 유형의 보안도 제공하지 않기 때문입니다. 대신 gitignore에 webpack을 추가하지 않는 한 비밀을 강화하는 것이 좋습니다. 더 나은 해결책이 있습니다.
기본적 으로이 구성을 사용하면 코드를 컴파일하면 모든 프로세스 env 변수가 전체 코드에서 제거되고 단일 프로세스 transform-inline-environment-variables
가 없습니다. 웹팩이 babel-loader를 호출하기 전에 env.js를 호출해야합니다. 이것이 바로 웹팩 호출입니다. babel.config.js 파일의 vars 배열은 env.js의 객체와 일치해야합니다. 이제해야 할 일이 하나뿐입니다. .env
거기에 모든 env 변수를 넣은 파일을 추가하십시오. 파일은 프로젝트의 루트에 있거나 원하는 위치에 자유롭게 추가해야합니다 .env.js 파일에서 동일한 위치를 설정하고 추가하십시오. 기니 고르
const dotFiles = ['.env'].filter(Boolean);
if (existsSync(dotFiles)) {
require("dotenv-expand")(require("dotenv").config((dotFiles)));
}
전체 babel + webpack + ts를 보려면 Heaw에서 가져옵니다.
https://github.com/EnetoJara/Node-typescript-babel-webpack.git
같은 논리가 반응과 다른 모든 NES에 적용됩니다.
config
---webpack.js
---env.js
src
---source code world
.env
bunch of dotFiles
env.js
"use strict";
/***
I took the main idea from CRA, but mine is more cooler xD
*/
const {realpathSync, existsSync} = require('fs');
const {resolve, isAbsolute, delimiter} = require('path');
const NODE_ENV = process.env.NODE_ENV || "development";
const appDirectory = realpathSync(process.cwd());
if (typeof NODE_ENV !== "string") {
throw new Error("falle and stuff");
}
const dotFiles = ['.env'].filter(Boolean);
if (existsSync(dotFiles)) {
require("dotenv-expand")(require("dotenv").config((dotFiles)));
}
process.env.NODE_PATH = (process.env.NODE_PATH || "")
.split(delimiter)
.filter(folder => folder && isAbsolute(folder))
.map(folder => resolve(appDirectory, folder))
.join(delimiter);
const ENETO_APP = /^ENETO_APP_/i;
module.exports = (function () {
const raw = Object.keys ( process.env )
.filter ( key => ENETO_APP.test ( key ) )
.reduce ( ( env, key ) => {
env[ key ] = process.env[ key ];
return env;
},
{
BABEL_ENV: process.env.ENETO_APP_BABEL_ENV,
ENETO_APP_DB_NAME: process.env.ENETO_APP_DB_NAME,
ENETO_APP_DB_PASSWORD: process.env.ENETO_APP_DB_PASSWORD,
ENETO_APP_DB_USER: process.env.ENETO_APP_DB_USER,
GENERATE_SOURCEMAP: process.env.ENETO_APP_GENERATE_SOURCEMAP,
NODE_ENV: process.env.ENETO_APP_NODE_ENV,
PORT: process.env.ENETO_APP_PORT,
PUBLIC_URL: "/"
} );
const stringyField = {
"process.env": Object.keys(raw).reduce((env, key)=> {
env[key]=JSON.stringify(raw[key]);
return env;
},{}),
};
return {
raw, stringyField
}
})();
플러그인이없는 웹팩 파일
"use strict";
require("core-js");
require("./env.js");
const path = require("path");
const nodeExternals = require("webpack-node-externals");
module.exports = env => {
return {
devtool: "source-map",
entry: path.join(__dirname, '../src/dev.ts'),
externals: [nodeExternals()],
module: {
rules: [
{
exclude: /node_modules/,
test: /\.ts$/,
use: [
{
loader: "babel-loader",
},
{
loader: "ts-loader"
}
],
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: "file-loader",
},
],
},
],
},
node: {
__dirname: false,
__filename: false,
},
optimization: {
splitChunks: {
automaticNameDelimiter: "_",
cacheGroups: {
vendor: {
chunks: "initial",
minChunks: 2,
name: "vendor",
test: /[\\/]node_modules[\\/]/,
},
},
},
},
output: {
chunkFilename: "main.chunk.js",
filename: "name-bundle.js",
libraryTarget: "commonjs2",
},
plugins: [],
resolve: {
extensions: ['.ts', '.js']
} ,
target: "node"
};
};
babel.config.js
module.exports = api => {
api.cache(() => process.env.NODE_ENV);
return {
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-transform-classes", {loose: true}],
["@babel/plugin-external-helpers"],
["@babel/plugin-transform-runtime"],
["@babel/plugin-transform-modules-commonjs"],
["transform-member-expression-literals"],
["transform-property-literals"],
["@babel/plugin-transform-reserved-words"],
["@babel/plugin-transform-property-mutators"],
["@babel/plugin-transform-arrow-functions"],
["@babel/plugin-transform-block-scoped-functions"],
[
"@babel/plugin-transform-async-to-generator",
{
method: "coroutine",
module: "bluebird",
},
],
["@babel/plugin-proposal-async-generator-functions"],
["@babel/plugin-transform-block-scoping"],
["@babel/plugin-transform-computed-properties"],
["@babel/plugin-transform-destructuring"],
["@babel/plugin-transform-duplicate-keys"],
["@babel/plugin-transform-for-of"],
["@babel/plugin-transform-function-name"],
["@babel/plugin-transform-literals"],
["@babel/plugin-transform-object-super"],
["@babel/plugin-transform-shorthand-properties"],
["@babel/plugin-transform-spread"],
["@babel/plugin-transform-template-literals"],
["@babel/plugin-transform-exponentiation-operator"],
["@babel/plugin-proposal-object-rest-spread"],
["@babel/plugin-proposal-do-expressions"],
["@babel/plugin-proposal-export-default-from"],
["@babel/plugin-proposal-export-namespace-from"],
["@babel/plugin-proposal-logical-assignment-operators"],
["@babel/plugin-proposal-throw-expressions"],
[
"transform-inline-environment-variables",
{
include: [
"ENETO_APP_PORT",
"ENETO_APP_NODE_ENV",
"ENETO_APP_BABEL_ENV",
"ENETO_APP_DB_NAME",
"ENETO_APP_DB_USER",
"ENETO_APP_DB_PASSWORD",
],
},
],
],
presets: [["@babel/preset-env",{
targets: {
node: "current",
esmodules: true
},
useBuiltIns: 'entry',
corejs: 2,
modules: "cjs"
}],"@babel/preset-typescript"],
};
};