Saya memiliki beberapa hal untuk pengembangan - mis. Ejekan yang saya ingin agar file build terdistribusi saya tidak membengkak.
Di RequireJS Anda dapat meneruskan konfigurasi dalam file plugin dan secara kondisional memerlukan hal-hal berdasarkan itu.
Untuk webpack sepertinya tidak ada cara untuk melakukan ini. Pertama-tama untuk membuat konfigurasi runtime untuk lingkungan, saya telah menggunakan resolusinya.alias untuk menunjuk kembali kebutuhan bergantung pada lingkungan, misalnya:
// All settings.
var all = {
fish: 'salmon'
};
// `envsettings` is an alias resolved at build time.
module.exports = Object.assign(all, require('envsettings'));
Kemudian saat membuat konfigurasi webpack saya dapat secara dinamis menetapkan file mana yang envsettings
menunjuk ke (yaitu webpackConfig.resolve.alias.envsettings = './' + env
).
Namun saya ingin melakukan sesuatu seperti:
if (settings.mock) {
// Short-circuit ajax calls.
// Require in all the mock modules.
}
Tapi jelas saya tidak ingin membangun file tiruan itu jika lingkungan tidak tiruan.
Saya mungkin dapat secara manual menunjuk kembali semua yang diperlukan ke file rintisan menggunakan resolusikan.alias lagi - tetapi apakah ada cara yang terasa kurang hacky?
Ada ide bagaimana saya bisa melakukan itu? Terima kasih.
sumber
Jawaban:
Anda dapat menggunakan plugin definisikan .
Saya menggunakannya dengan melakukan sesuatu yang sederhana seperti ini di file build webpack Anda di mana
env
jalur ke file yang mengekspor objek pengaturan:// Webpack build config plugins: [ new webpack.DefinePlugin({ ENV: require(path.join(__dirname, './path-to-env-files/', env)) }) ] // Settings file located at `path-to-env-files/dev.js` module.exports = { debug: true };
dan kemudian ini di kode Anda
if (ENV.debug) { console.log('Yo!'); }
Ini akan menghapus kode ini dari file build Anda jika kondisinya salah. Anda dapat melihat contoh build Webpack yang berfungsi di sini .
sumber
env
. Melihat melalui contoh itu, sepertinya mereka menangani bendera itu melalui gulp dan yarg yang tidak digunakan semua orang."globals": { "ENV": true }
ke .eslintrc AndaTidak yakin mengapa jawaban "webpack.DefinePlugin" adalah yang teratas di mana pun untuk menentukan impor / kebutuhan berbasis Lingkungan.
The masalah dengan pendekatan itu adalah bahwa Anda masih memberikan semua modul yang ke klien -> cek dengan Webpack-bundle-analyezer misalnya. Dan tidak mengurangi ukuran bundle.js Anda sama sekali :)
Jadi yang benar-benar berfungsi dengan baik dan lebih logis adalah: NormalModuleReplacementPlugin
Jadi daripada melakukan persyaratan bersyarat on_client -> cukup tidak menyertakan file yang tidak diperlukan ke bundel di tempat pertama
Semoga membantu
sumber
Gunakan
ifdef-loader
. Di file sumber Anda, Anda dapat melakukan hal-hal seperti/// #if ENV === 'production' console.log('production!'); /// #endif
webpack
Konfigurasi yang relevan adalahconst preprocessor = { ENV: process.env.NODE_ENV || 'development', }; const ifdef_query = require('querystring').encode({ json: JSON.stringify(preprocessor) }); const config = { // ... module: { rules: [ // ... { test: /\.js$/, exclude: /node_modules/, use: { loader: `ifdef-loader?${ifdef_query}`, }, }, ], }, // ... };
sumber
Saya akhirnya menggunakan sesuatu yang mirip dengan Jawaban Matt Derrick , tetapi khawatir tentang dua poin:
ENV
(Yang buruk untuk konfigurasi besar).require(env)
menunjuk ke file yang berbeda.Apa yang saya dapatkan adalah komposer sederhana yang membangun objek konfigurasi dan memasukkannya ke modul konfigurasi.
Berikut adalah struktur file yang saya gunakan untuk ini:
Ini
main.js
menampung semua hal konfigurasi default:// main.js const mainConfig = { apiEndPoint: 'https://api.example.com', ... } module.exports = mainConfig;
Satu
dev.js
-production.js
satunya penyimpanan config yang menggantikan konfigurasi utama:// dev.js const devConfig = { apiEndPoint: 'http://localhost:4000' } module.exports = devConfig;
Bagian yang penting adalah
webpack.config.js
yang menyusun konfigurasi dan menggunakan DefinePlugin untuk menghasilkan variabel lingkungan__APP_CONFIG__
yang menampung objek config yang disusun:const argv = require('yargs').argv; const _ = require('lodash'); const webpack = require('webpack'); // Import all app configs const appConfig = require('./config/main'); const appConfigDev = require('./config/dev'); const appConfigProduction = require('./config/production'); const ENV = argv.env || 'dev'; function composeConfig(env) { if (env === 'dev') { return _.merge({}, appConfig, appConfigDev); } if (env === 'production') { return _.merge({}, appConfig, appConfigProduction); } } // Webpack config object module.exports = { entry: './src/app.js', ... plugins: [ new webpack.DefinePlugin({ __APP_CONFIG__: JSON.stringify(composeConfig(ENV)) }) ] };
Langkah terakhir sekarang adalah
config.js
, terlihat seperti ini (Menggunakan sintaks ekspor impor es6 di sini karena di bawah webpack):const config = __APP_CONFIG__; export default config;
Di Anda,
app.js
Anda sekarang bisa menggunakanimport config from './config';
untuk mendapatkan objek konfigurasi.sumber
cara lain adalah menggunakan file JS sebagai
proxy
, dan membiarkan file itu memuat modul yang diinginkancommonjs
, dan mengekspornya sebagaies2015 module
, seperti ini:// file: myModule.dev.js module.exports = "this is in dev" // file: myModule.prod.js module.exports = "this is in prod" // file: myModule.js let loadedModule if(WEBPACK_IS_DEVELOPMENT){ loadedModule = require('./myModule.dev.js') }else{ loadedModule = require('./myModule.prod.js') } export const myString = loadedModule
Kemudian Anda dapat menggunakan modul ES2015 di aplikasi Anda secara normal:
// myApp.js import { myString } from './store/myModule.js' myString // <- "this is in dev"
sumber
webpack.optimize.UglifyJsPlugin()
, pengoptimalan webpack tidak akan memuat modul, karena kode baris di dalam kondisional selalu salah, jadi webpack menghapusnya dari bundel yang dihasilkanMenghadapi masalah yang sama dengan OP dan diperlukan, karena lisensi, untuk tidak menyertakan kode tertentu dalam build tertentu, saya mengadopsi webpack-conditional-loader sebagai berikut:
Dalam perintah build saya, saya menetapkan variabel lingkungan secara tepat untuk build saya. Misalnya 'demo' di package.json:
... "scripts": { ... "buildDemo": "./node_modules/.bin/webpack --config webpack.config/demo.js --env.demo --progress --colors", ...
Sedikit membingungkan yang hilang dari dokumentasi yang saya baca adalah bahwa saya harus membuatnya terlihat selama proses pembuatan dengan memastikan variabel env saya dimasukkan ke dalam proses global sehingga di webpack.config / demo.js saya:
/* The demo includes project/reports action to access placeholder graphs. This is achieved by using the webpack-conditional-loader process.env.demo === true */ const config = require('./production.js'); config.optimization = {...(config.optimization || {}), minimize: false}; module.exports = env => { process.env = {...(process.env || {}), ...env}; return config};
Dengan ini, saya dapat mengecualikan apa pun secara kondisional, memastikan bahwa kode terkait apa pun diguncang dengan benar dari JavaScript yang dihasilkan. Misalnya di routes.js saya konten demo disimpan dari build lain sebagai berikut:
... // #if process.env.demo import Reports from 'components/model/project/reports'; // #endif ... const routeMap = [ ... // #if process.env.demo {path: "/project/reports/:id", component: Reports}, // #endif ...
Ini bekerja dengan webpack 4.29.6.
sumber
Saya kesulitan mengatur env di konfigurasi webpack saya. Yang biasanya saya inginkan adalah menyetel env agar dapat dijangkau di dalam
webpack.config.js
,postcss.config.js
dan di dalam aplikasi titik masuk itu sendiri (index.js
biasanya). Saya berharap temuan saya dapat membantu seseorang.Solusi yang saya dapatkan adalah dengan meneruskan
--env production
atau--env development
, dan kemudian mengatur mode di dalamwebpack.config.js
. Namun, itu tidak membantu saya membuatenv
dapat diakses di tempat yang saya inginkan (lihat di atas), jadi saya juga perlu menyetelprocess.env.NODE_ENV
secara eksplisit, seperti yang direkomendasikan di sini . Bagian paling relevan yang saya miliki diwebpack.config.js
ikuti di bawah ini.... module.exports = mode => { process.env.NODE_ENV = mode; if (mode === "production") { return merge(commonConfig, productionConfig, { mode }); } return merge(commonConfig, developmentConfig, { mode }); };
sumber
Gunakan variabel lingkungan untuk membuat penerapan dev dan prod:
https://webpack.js.org/guides/environment-variables/
sumber
Meskipun ini bukan solusi terbaik, ini mungkin berhasil untuk beberapa kebutuhan Anda. Jika Anda ingin menjalankan kode berbeda di node dan browser menggunakan ini berfungsi untuk saya:
if (typeof window !== 'undefined') return } //run node only code now
sumber