Komut satırı bağımsız değişkenlerini npm komut dosyasına gönderme


819

scriptsBenim kısmı package.jsonhalen şuna benzer:

"scripts": {
    "start": "node ./script.js server"
}

... yani npm startsunucuyu başlatmak için çalışabilirim . Çok uzak çok iyi.

Ancak, gibi bir şey çalıştırmak npm start 8080ve argüman (lar) geçirilmiş olmak istiyorum script.js(eg npm start 8080=> node ./script.js server 8080). Mümkün mü?

Yanıtlar:


1132

Düzenleme 2014.10.30: Bu kadar args geçmek mümkündür npm runNPM 2.0.0 itibariyle

Sözdizimi aşağıdaki gibidir:

npm run <command> [-- <args>]

Gerekli not edin --. Geçirilen params ayırmak için gereklidir npmSenaryonuzun geçirilen kendini komuta ve params.

Yani eğer varsa package.json

"scripts": {
    "grunt": "grunt",
    "server": "node server.js"
}

Sonra aşağıdaki komutlar eşdeğer olur:

grunt task:target => npm run grunt -- task:target

node server.js --port=1337 => npm run server -- --port=1337

Parametre değerini almak için bu soruya bakın . Adlandırılmış parametreleri okumak için, muhtemelen yarg veya minimist gibi bir ayrıştırma kütüphanesi kullanmak en iyisidir ; nodejs process.argvkomut satırı parametre değerlerini içeren global olarak ortaya çıkar , ancak bu düşük seviyeli bir API'dir (işletim sistemi tarafından çalıştırılabilir düğüme sağlanan boşlukla ayrılmış dizeler dizisi).


Edit 2013.10.03: Şu anda doğrudan mümkün değil. Ancak , istediğiniz davranışı uygulamak için ilgili bir GitHub sorunu varnpm . Mutabakat bunun uygulanmasını sağlamak gibi görünüyor, ancak daha önce çözülmekte olan başka bir konuya bağlı.


Orijinal cevap: Bir çeşit geçici çözüm olarak (çok kullanışlı olmasa da) şunları yapabilirsiniz:

Adresinin paket ismini söyle package.jsonIS myPackageve siz de

"scripts": {
    "start": "node ./script.js server"
}

Sonra ekleyin package.json:

"config": {
    "myPort": "8080"
}

Ve sizin script.js:

// defaulting to 8080 in case if script invoked not via "npm run-script" but directly
var port = process.env.npm_package_config_myPort || 8080

Bu şekilde, varsayılan olarak npm start8080 kullanır. Bunu yapılandırabilirsiniz (değer npm, dahili depolama biriminde depolanır):

npm config set myPackage:myPort 9090

Daha sonra, çağırırken npm start9090 kullanılır (varsayılan değer package.jsongeçersiz kılınır).


1
Bu aynı zamanda yargs; sonra tüm parametreler --betiğinizde mükemmel bir şekilde ayrıştırılabilir.
Thomas

11
AFAIKS, bu sadece betiklerinizin sonuna parametre eklemeyi mümkün kılar .. ya ortada parametrelere ihtiyacınız varsa?
Spock

108
-- --argskutsal bok bu garip ama tamam
ağustos

9
@Spock Kabuk işlevlerini kullanabilirsiniz. İşte "npm run lint - -f unix": "lint": "f () {eslint -f kod karesi $ @. tslint && echo 'lint clean!';}; f "
ecmanaut

3
"MyPackage: myPort 9090" değerini ayarlamanın en iyi yolu, "--myPackage: myPort = 9090" komutunun bir yapılandırma işaretidir. - keithcirkel.co.uk/how-to-use-npm-as-a-build -tool
chrismarx

223

Bir şey çalıştırmak mümkün istedi gibi npm start 8080 . Bu, script.jsdosyaları aşağıdaki gibi değiştirmeye veya yapılandırmaya gerek kalmadan mümkündür .

Örneğin, "scripts"JSON değerinize şunu ekleyin :

"start": "node ./script.js server $PORT"

Ve sonra komut satırından:

$ PORT=8080 npm start

Bunun bash ve npm 1.4.23 kullanarak çalıştığını doğruladım. Bu geçici çözümün GitHub npm sorununun # 3494 çözülmesini gerektirmediğini unutmayın .


19
Bu gerçekten iyi çalışıyor. Ayrıca node ./script.js server ${PORT:-8080}isteğe bağlı yapmak gibi bir şey de yapabilirsiniz .
graup

7
Git bash ile pencerelerde bunu yapamıyorum gibi görünüyor. Belki çalıştıran var mı? (aynı komut
ubuntu'da da

3
Hey @graup bu benim için çalıştı NODE_PORT=${PORT=8080}(eşittir notive) ama değil: - sözdizimi
MaieonBrix

14
Bu, platformlar arası çalışmaz! Örneğin Windows'ta komutun olması gerekir node ./script.js server %PORT%. Cross-var ve cross-env kullanmayı düşünün .
Stijn de Witt

Env değişkenlerini cli argümanları olarak kullanmanın usecase'i oldukça sınırlı görünüyor? Env değişkenlerini, varsayılanları ve yapılandırmayı genel olarak işlemek için yapılandırma modülü gibi bir şey de kullanabilir.
Mr5o1

93

Ayrıca şunları da yapabilirsiniz:

İçinde package.json:

"scripts": {
    "cool": "./cool.js"
}

İçinde cool.js:

 console.log({ myVar: process.env.npm_config_myVar });

CLI'de:

npm --myVar=something run-script cool

Çıktı gerekir:

{ myVar: 'something' }

Güncelleme: npm 3.10.3 kullanarak, process.env.npm_config_değişkenleri küçültüyor gibi görünüyor ? Ben de kullanıyorum better-npm-runben emin bu vanilya varsayılan davranış olup olmadığını değilim bu yüzden, ama bu cevap olduğunu çalışma. Bunun yerine process.env.npm_config_myVar,process.env.npm_config_myvar


4
Teşekkürler bu benim için çalıştı! Ne eksik özellikle komut satırında belirttiğiniz değişken adına "npm_config_" öneki.
jp093121

2
Bu yanlış. process.env.npm_config_myVardeğeri değil true değerini döndürür.
Karl Morrison

1
Npm sürüm 6.8.0 ile çalışır, ancak yalnızca değişken adı için küçük harf kullandığımda. görünüyor lilke npm küçük harf değiştirmek
Ofir Meguri

Harika bir çözüm, npm 6.5.0'da küçük harfle çalışır
GavinBelson

78

jakub.g'nin cevabı doğru, ancak homurdanan bir örnek biraz karmaşık görünüyor.

Daha basit cevabım:

- Bir npm komut dosyasına komut satırı argümanı gönderme

Bir npm komut dosyasına komut satırı bağımsız değişkenleri göndermek için sözdizimi:

npm run [command] [-- <args>]

Webpack dev sunucusunu başlatmak için paketimizde bir npm başlangıç ​​görevimiz olduğunu düşünün:

"scripts": {
  "start": "webpack-dev-server --port 5000"
},

Bunu komut satırından npm start

Şimdi bir bağlantı noktasında npm betiğine geçmek istiyorsak:

"scripts": {
  "start": "webpack-dev-server --port process.env.port || 8080"
},

bunu çalıştırmak ve örneğin komut satırı üzerinden 5000 bağlantı noktasını geçmek aşağıdaki gibi olacaktır:

npm start --port:5000

- package.json config kullanımı:

Tarafından belirtildiği gibi jakub.g , alternatif olarak bir config params ayarlayabilirsiniz package.json

"config": {
  "myPort": "5000"
}

"scripts": {
  "start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080"
},

npm start yapılandırmanızda belirtilen bağlantı noktasını kullanır veya alternatif olarak geçersiz kılabilirsiniz

npm config set myPackage:myPort 3000

- npm betiğinizde bir parametre belirleme

Npm betiğinizde bir değişken kümesi okuma örneği. Bu örnekteNODE_ENV

"scripts": {
  "start:prod": "NODE_ENV=prod node server.js",
  "start:dev": "NODE_ENV=dev node server.js"
},

içinde NODE_ENV oku server.js ya eşya veya dev

var env = process.env.NODE_ENV || 'prod'

if(env === 'dev'){
    var app = require("./serverDev.js");
} else {
    var app = require("./serverProd.js");
}

5
gibi o sözdizimi not "start:prod": "NODE_ENV=prod node server.js"içinde package.jsonWindows üzerinde olmaz çalışması, kullanmak sürece çapraz env
jakub.g

2
Düzeltme ? : bu eğitimde açıklanan kullanımına göre "start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080" },olmalıdır . Süreç ref görünüşte javascript içinde kullanılabilir. "start": "webpack-dev-server --port $npm_package_config_myPort || 8080" },
Aaron Roller


34

process.argvKodunuzda kullanın , daha sonra $*komut dosyalarınızın değer girişine bir son verin.

Örnek olarak, sağlanan argümanları standart dışı bırakmak için günlüğe kaydeden basit bir komut dosyası ile deneyin echoargs.js:

console.log('arguments: ' + process.argv.slice(2));

package.json:

"scripts": {
    "start": "node echoargs.js $*"
}

Örnekler:

> npm start 1 2 3
arguments: 1,2,3

process.argv[0]çalıştırılabilir (düğüm), process.argv[1]betiğinizdir.

Npm v5.3.0 ve düğüm v8.4.0 ile test edildi


Bağımsız --değişkenlere ekledikten sonra çalışmaz , örn. - npm run demo.js --skip, fazladan eklenirse çalışır --, örn. -npm run demo.js -- --skip
Shreyas

Ayrı bir echoargs.jskomut dosyası olmadan bu yöntemi kullanabilir misiniz ?
Joshua Pinter

@JoshuaPinter echoargs.js sadece örnek amaçlıdır, bunu netleştirmek için cevabımı düzenleyeceğim
Peter

@Peter Doğru, ancak bir komut dosyası olması gerekiyor. Ben kullanır ki komut dosyası oluşturmak için çalışıyorum adbbir zorlamaya .dbAndroid emülatörü dosyayı ve yerel yolu için bir param kabul .dbilk parametresidir buna itme için dosyanın, adb push. Böyle bir şey: "db:push": "adb push process.argv.slice(2) /data/data/com.cntral.app/databases/database.db"ve ben onu aramak istiyorum npm run db:push /Users/joshuapinter/Downloads/updated.db. Düşüncesi olan var mı?
Joshua Pinter

21

Bir npm betiğinin ortasına argümanları iletmek istiyorsanız, bunların sonuna sonuna eklenmesinin aksine, satır içi ortam değişkenleri iyi çalışıyor gibi görünüyor:

"scripts": {
  "dev": "BABEL_ARGS=-w npm run build && cd lib/server && nodemon index.js",
  "start": "npm run build && node lib/server/index.js",
  "build": "mkdir -p lib && babel $BABEL_ARGS -s inline --stage 0 src -d lib",
},

Burada, saat bayrağını babil'e npm run devgeçirir -w, ancak npm run startsadece bir kez düzenli bir yapı çalıştırır.


Buna CLI'den nasıl denir?
bwobst

@dresdin npm run dev,npm start
TJ

2
İhtiyaç kullanmak çapraz env Windows üzerinde kullanmak.
fracz

8

Geçmişte bu tek astarı kullanıyordum ve kısa bir süre sonra Node.js'den kısa bir süre sonra onu yeniden denemek ve yeniden keşfetmek zorunda kaldı. @Francoisrv tarafından bahsedilen çözüme benzer şekilde node_config_*değişkenleri kullanır .

Aşağıdaki minimum package.jsondosyayı oluşturun:

{
  "name": "argument",
  "version": "1.0.0",
  "scripts": {
    "argument": "echo \"The value of --foo is '${npm_config_foo}'\""
  }
}

Aşağıdaki komutu çalıştırın:

npm run argument --foo=bar

Aşağıdaki çıktıya dikkat edin:

--Foo 'bar' değeri

Tüm bunlar npm resmi belgelerinde güzel bir şekilde belgelenmiştir:

Not: Ortam Değişkenleri başlığı komut içindeki değişkenler belgelerinde tanımlanır ne kadar farklı davranır mı olduğunu açıklar. Büyük / küçük harfe duyarlılık söz konusu olduğunda , argümanın boşlukla mı yoksa eşittir işaretiyle mi tanımlandığı da bu doğrudur .

Not: Kısa çizgilerle bir bağımsız değişken kullanıyorsanız, bunlar karşılık gelen ortam değişkenindeki alt çizgilerle değiştirilir. Örneğin, npm run example --foo-bar=bazbuna karşılık gelir ${npm_config_foo_bar}.

Not: olmayan WSL Windows kullanıcıları için, aşağıda ... TL @Doctor Blue'nun yorumları görmek; DR değiştirin ${npm_config_foo}ile %npm_config_foo%.


Merhaba. Örneğini kullanmaya çalışıyorum ama korkarım ki benim için çalışmıyor. "Argüman" betiğinizi kopyalayıp yapıştırdım ve komutun çalıştırılması ( npm run argument --foo=bar) için de aynısını yaptım , ancak değişken değiştirilmedi:"The value of --foo is '${npm_config_foo}'" . Önemli ise, Windows 10'da NPM'nin 6.9.0 sürümü ile çalışıyor.
Doktor Blue

@DoctorBlue Ahh, Düğüm ve Windows her zaman iyi oynamıyor ... Bu makale npm komut dosyalarındaki ortam değişkenlerine biraz ışık tutabilir: (TL; DR komutları, başka bir kabuktan başlansa bile doğrudan ana bilgisayar işletim sistemine gider) blog .risingstack.com / node-js-windows-10-tutorial /… Kurulumunuzda emin değilim, ancak Düğüm'ü çalıştırmak için Git Bash kullanıyorsanız, WSL :) dokümanlar
Andrew Odri

1
Bunu anladım. Sadece kullanmak zorunda kaldı %npm_config_foo%. Saf Windows komut satırı / powershell burada. (Başka seçeneğiniz de yok.)
Doctor Blue

6

Bu gerçekten sorunuzu cevaplamıyor ancak bunun yerine her zaman ortam değişkenlerini kullanabilirsiniz:

"scripts": {
    "start": "PORT=3000 node server.js"
}

Sonra server.js dosyanızda:

var port = process.env.PORT || 3000;

1
Unix platformunda olduğunuz sürece bu iyidir. Maalesef Windows ile çalışmaz, çünkü bu kendi kurallarına sahiptir.
Juho Vepsäläinen

6

Yukarıdaki cevapların çoğu sadece argümanları npm olarak adlandırılan NodeJS betiğinize aktarmayı kapsar. Benim çözümüm genel kullanım içindir.

Sadece npm betiğini bir kabuk yorumlayıcısı (örn. sh) Çağrısı ile sarın ve argümanları her zamanki gibi iletin . Bunun tek istisnası, ilk argüman numarasının0 .

Örneğin, npm betiğini eklemek istersiniz someprogram --env=<argument_1>, burada someprogramsadeceenv argüman:

package.json

"scripts": {
  "command": "sh -c 'someprogram --env=$0'"
}

Çalıştırdığınızda:

% npm run -s command my-environment
my-environment

Teşekkürler! Bu mükemmeldi!
Felipe Desiderati

Basit ve zarif! MS DOS kabuğunda çalışmaz.
n370

3

Gördüğüm kadarıyla, insanlar betiği daha basit bir şekilde çalıştırmak istediklerinde package.json komut dosyalarını kullanırlar. Örneğin, nodemonyerel düğüm_modüllerinde yüklü olanı kullanmak için nodemondoğrudan clidan arayamayız , ancak kullanarak arayabiliriz ./node_modules/nodemon/nodemon.js. Yani, bu uzun yazmayı basitleştirmek için bunu koyabiliriz ...

    ...

    Kodlar: {
      'start': 'nodemon app.js'
    }

    ...

... sonra npm startilk argüman olarak app.js olan 'nodemon'u kullanmaya çağırın .

Söylemeye çalıştığım şey, sunucunuzu nodekomutla başlatmak istiyorsanız, kullanmanız gerektiğini düşünmüyorum scripts. Yazmak npm startveya node app.jsaynı çabayı gösterir.

Ancak nodemon, dinamik bir argüman kullanmak istiyorsanız ve kullanmak istemiyorsanız,script ikisini . Bunun yerine symlink'i kullanmayı deneyin.

Örneğin, ile taşıma özelliğini kullanarak sequelize. Bir sembolik bağlantı oluşturuyorum ...

ln -s node_modules/sequelize/bin/sequelize sequelize

... Ve dediğimde herhangi bir tartışmayı geçebilirim ...

./sequlize -h /* show help */

./sequelize -m /* upgrade migration */

./sequelize -m -u /* downgrade migration */

vb...

Bu noktada, symlink kullanmak anlamanın en iyi yoludur, ancak bunun en iyi uygulama olduğunu düşünmüyorum.

Ayrıca cevabımla ilgili görüşlerinizi umuyorum.


1
Bu soruya hiç cevap vermiyor. Nasıl 6 upvotes var bilmiyorum, ama tebrikler :)
Dan Dascalescu

2

Not: Bu yaklaşım,package.json anında alternatifiniz yoksa kullanın.

Komut satırı argümanları gibi komutlarıma geçmek zorunda kaldım:

"scripts": {
    "start": "npm run build && npm run watch",
    "watch": "concurrently  \"npm run watch-ts\" \"npm run watch-node\"",
    ...
}

Yani, bu benim app ile başlatmak anlamına gelir npm run start.

Şimdi bazı argümanlar geçmek istiyorsanız, belki ile başlar:

npm run start -- --config=someConfig

Ne yapar geçerli: npm run build && npm run watch -- --config=someConfig. Buradaki problem, her zaman argümanları kodun sonuna ekler. Bu, tüm zincirlenmiş komut dosyalarının bu argümanları almadığı anlamına gelir (Args herkes tarafından istenebilir veya istenmeyebilir, ancak bu farklı bir hikaye.). Ayrıca, bağlantılı komut dosyaları çağrıldığında, bu komut dosyaları iletilen bağımsız değişkenleri alamaz. Yani watchkomut dosyası iletilen argümanları alamaz.

Uygulamamın üretim kullanımı .exe , bu yüzden exe'deki argümanları geçmek iyi çalışır, ancak geliştirme sırasında bunu yapmak istiyorsanız, prolamatik olur.

Bunu başarmak için uygun bir yol bulamadım, bu yüzden denedim.

Bir javascript dosyası oluşturduk: start-script.jsuygulamanın üst düzeyinde, bir "default.package.json" var ve "package.json" korumak yerine, "default.package.json" korumak. Amacı, bu komut dosyalarına iletilen bağımsız değişkenleri start-script.jsonokumak default.package.json, ayıklamak scriptsve npm run scriptnamearamaktır. Bundan sonra, yeni bir oluşturur package.jsonve değiştirilmiş komut dosyalarıyla varsayılan.package.json'dan verileri kopyalar ve çağırır npm run start.

const fs = require('fs');
const { spawn } = require('child_process');

// open default.package.json
const defaultPackage = fs.readFileSync('./default.package.json');
try {
    const packageOb = JSON.parse(defaultPackage);
    // loop over the scripts present in this object, edit them with flags
    if ('scripts' in packageOb && process.argv.length > 2) {

        const passedFlags = ` -- ${process.argv.slice(2).join(' ')}`;
        // assuming the script names have words, : or -, modify the regex if required.
        const regexPattern = /(npm run [\w:-]*)/g;
        const scriptsWithFlags = Object.entries(packageOb.scripts).reduce((acc, [key, value]) => {
            const patternMatches = value.match(regexPattern);
            // loop over all the matched strings and attach the desired flags.
            if (patternMatches) {
                for (let eachMatchedPattern of patternMatches) {
                    const startIndex = value.indexOf(eachMatchedPattern);
                    const endIndex = startIndex + eachMatchedPattern.length;
                    // save the string which doen't fall in this matched pattern range.
                    value = value.slice(0, startIndex) + eachMatchedPattern + passedFlags + value.slice(endIndex);
                }
            }
            acc[key] = value;
            return acc;
        }, {});
        packageOb.scripts = scriptsWithFlags;
    }

    const modifiedJSON = JSON.stringify(packageOb, null, 4);
    fs.writeFileSync('./package.json', modifiedJSON);

    // now run your npm start script
    let cmd = 'npm';
    // check if this works in your OS
    if (process.platform === 'win32') {
        cmd = 'npm.cmd';    // https://github.com/nodejs/node/issues/3675
    }
    spawn(cmd, ['run', 'start'], { stdio: 'inherit' });

} catch(e) {
    console.log('Error while parsing default.package.json', e);
}

Şimdi, yerine yapmanın npm run start, yapmamnode start-script.js --c=somethis --r=somethingElse

İlk koşu iyi görünüyor, ancak tam olarak test edilmedi. Uygulama geliştirme için isterseniz kullanın.


1

Bu soruyu, sequelize seed: create cli komutunu çalıştırmayla ilgili sorunumu çözmeye çalışırken buldum:

node_modules/.bin/sequelize seed:generate --name=user

Konuya geleyim. Paketimde kısa bir komut dosyası olmasını istedim. dosyasında ve aynı zamanda --name bağımsız değişkenini sağlamak istedim

Cevap bazı deneylerden sonra geldi. İşte package.json'daki komutum

"scripts: {
  "seed:generate":"NODE_ENV=development node_modules/.bin/sequelize seed:generate"
}

... ve burada kullanıcı için bir tohum dosyası oluşturmak üzere terminalde çalıştırmaya bir örnek

> yarn seed:generate --name=user

> npm run seed:generate -- --name=user

Bilginize

yarn -v
1.6.0

npm -v
5.6.0

2
Bu, 2013'te kabul edilen cevapta açıklananla aynı teknik -- --arg1, ...midir?
Dan Dascalescu

2
Tamam, o zaman neden cevabı tekrarlıyorsun?
Dan Dascalescu

Farklı bir kullanım örneği paylaştım, belli değil mi?
Serge Seletskyy

2
Farklı bir cevapta daha önce açıklanmış bir teknik için başka bir örnek paylaşmak istersem, örneğimi bu cevaba yorum olarak eklerdim.
Dan Dascalescu

1
gotcha, bir dahaki sefere bu şekilde yapacak
Serge Seletskyy

0

npm run script_target - <argument> Temelde bu komut satırı argümanlarını geçirmenin bir yoludur, ancak betiğin bir komutu çalıştırıyormuşum gibi çalışan tek bir komutu olması durumunda çalışır, yani npm run start - 4200

"script":{
       "start" : "ng serve --port="
 }

Bu komut satırı parametrelerini iletmek için çalışır ancak npm run build c: / workspace / file gibi bir komuttan daha fazlasını birlikte çalıştırırsak

"script":{
       "build" : "copy c:/file <arg> && ng build"
 } 

ancak c: / file && ng build c: / work space / file çalıştırılırken bunun gibi bir yorumlayıcı olacaktır ve bizden şu kopya bekleniyor : c: / file c: / work space / file && ng build

Not: - Bu nedenle komut satırı parametresi, bir komut dosyasında yalnızca bir komut olması durumunda beklenen reklamlarda çalışır.

Yukarıda bazılarının yazdığı ve komut satırı parametresine $ sembolü kullanarak erişebileceğiniz bazı cevapları okudum ama bu işe yaramayacak


0

Zaten onaylanmış bir cevap olduğunu biliyorum, ama bu JSON yaklaşımını seviyorum.

npm start '{"PROJECT_NAME_STR":"my amazing stuff", "CRAZY_ARR":[0,7,"hungry"], "MAGICAL_NUMBER_INT": 42, "THING_BOO":true}';

Genellikle bir proje adı gibi ihtiyacım var 1 var, bu yüzden bu hızlı n 'basit buluyorum.

Ayrıca genellikle paketimde böyle bir şey var. Json

"scripts": {
    "start": "NODE_ENV=development node local.js"
}

Ve açgözlü olarak "hepsini" istiyorum, NODE_ENV ve CMD hattı arg şeyler istiyorum.

Bu gibi şeylere dosyanızdan erişebilirsiniz (benim durumumda local.js)

console.log(process.env.NODE_ENV, starter_obj.CRAZY_ARR, starter_obj.PROJECT_NAME_STR, starter_obj.MAGICAL_NUMBER_INT, starter_obj.THING_BOO);

Sadece bu bitin üstünde olmanız gerekiyor (v10.16.0 btw kullanıyorum)

var starter_obj = JSON.parse(JSON.parse(process.env.npm_config_argv).remain[0]);

Anyhoo, soru zaten cevaplandı. Bu yöntemi çok kullandığım için paylaşacağımı düşündüm.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.