1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        【 Node.js】你應(yīng)該知道的 NPM 知識(shí)都在這!

        共 12166字,需瀏覽 25分鐘

         ·

        2021-02-18 15:34


        為什么寫這篇文章

        很多 Node.js 開發(fā)者,都知道有 package.json 這個(gè)文件,也多少都了解一些 npm 知識(shí),但是可能沒有系統(tǒng)的學(xué)習(xí)過,這部分的知識(shí)對(duì)于開發(fā)一個(gè) ?cli 工具,發(fā)布自己的 npm 包都很常用,開發(fā)中也會(huì)經(jīng)常用到npm script內(nèi)容,系統(tǒng)的學(xué)習(xí)一下確實(shí)會(huì)有所幫助,上面三個(gè)場(chǎng)景如果你都用不到,配置上節(jié)約時(shí)間,知其所以然也是有必要的!

        本文你能學(xué)到哪些?

        Package.json 知識(shí)全覽圖

        文章比較長(zhǎng),希望耐心看完!

        寫文本的目標(biāo):希望再遇到package.json ,npm 相關(guān)的問題,不用再去搜索,一篇文章全覆蓋,不一定全掌握,知道我這里都有,需要時(shí)候能直接來查就好了,也為了方便自己后面查閱。(本文主要講的部分是 npm script,個(gè)人認(rèn)為很常用,一些文章都沒有講)

        好了,開始我們的正文學(xué)習(xí)吧。

        package.json 如何產(chǎn)生的

        npm init

        npm init 命令用來初始化一個(gè)簡(jiǎn)單的 package.json 文件,執(zhí)行該命令后終端會(huì)依次詢問 name, version, description 等字段。

        npm init 默認(rèn)執(zhí)行行為

        我們?cè)趫?zhí)行 npm init 的時(shí)候,會(huì)有一個(gè)初始化 pacakge.json 過程,然后一路回車,其實(shí)可以直接使用 npm init --yes 在命令后追加 --yes 參數(shù)即可,其作用與一路回車相同,這樣生成的文件中就包含 package.json 文件

        自定義 npm init 行為

        npm init 命令的原理并不復(fù)雜,調(diào)用 shell 腳本,輸出一個(gè)初始化的 package.json 文件。所以相應(yīng)地,自定義 npm init 命令的實(shí)現(xiàn)方式也很簡(jiǎn)單,在電腦 npmStudy 目錄創(chuàng)建一個(gè) .npm-init.js 即可,該文件的 module.exports 即為 package.json 配置內(nèi)容,需要獲取用戶輸入時(shí)候,使用 prompt() 方法即可。例如編寫這樣的 ~/.npm-init.js

        const?desc?=?prompt('description?',?'A?new?package...')
        const?bar?=?prompt('bar?',?'')
        const?count?=?prompt('count?',?'42')

        module.exports?=?{
        ??key:?'value',
        ??foo:?{
        ????bar:?bar,
        ????count:?count
        ??},
        ??name:?prompt('name?',?process.cwd().split('/').pop()),
        ??version:?prompt('version?',?'0.1.0'),
        ??description:?desc,
        ??main:?'index.js',
        }

        然后在 /npmStudy 目錄下執(zhí)行 npm init 會(huì)出現(xiàn)下圖中對(duì)一系列操作

        然后生成 package.json 文件。到這里一個(gè) npm init 簡(jiǎn)單自定義過程結(jié)束,知道了兩種生成 pacakge.json 的方式

        package.json 中的常規(guī)屬性

        對(duì)于常規(guī)屬性都知道的可以忽略,繼續(xù)往下看 npm script 主要想講的部分。

        npm 中的依賴包

        這里只說我們常用的兩個(gè)依賴包 ?dependenicesdevDependenices,其它的一些依賴包只有作為包的發(fā)布者才會(huì)用到,需要的小伙伴自行查看文檔。

        dependenices

        通過命令npm install/i packageName -S/--save把包裝在此依賴項(xiàng)里。如果沒有指定版本,直接寫一個(gè)包的名字,則安裝當(dāng)前npm倉(cāng)庫(kù)中這個(gè)包的最新版本。如果要指定版本的,可以把版本號(hào)寫在包名后面,比如npm i [email protected] -S。

        npm 5.x開始,可以不用手動(dòng)添加-S/--save指令,直接執(zhí)行npm i packageName把依賴包添加到dependencies中去。

        ?"dependencies":?{
        ??????"lodash":?"^4.17.13",
        ??????"moment":?"^2.24.0",
        ?}

        devDependenices

        有一些包有可能你只是在開發(fā)環(huán)境中用到,例如你用于檢測(cè)代碼規(guī)范的 eslint ,用于進(jìn)行測(cè)試的 jest ,用戶使用你的包時(shí)即使不安裝這些依賴也可以正常運(yùn)行,反而安裝他們會(huì)耗費(fèi)更多的時(shí)間和資源,所以你可以把這些依賴添加到 devDependencies 中,這些依賴照樣會(huì)在你本地進(jìn)行 npm install 時(shí)被安裝和管理,但是不會(huì)被安裝到生產(chǎn)環(huán)境:

        ?"devDependencies":?{
        ??????"jest":?"^24.3.1",
        ??????"eslint":?"^6.1.0",
        ?}

        二者簡(jiǎn)單對(duì)比

        • devDependencies 主要是存放用于本地開發(fā)的
        • dependencies 會(huì)在我們開發(fā)的時(shí)候帶到線上
        • -D 會(huì)添加到 devDependencies 里面,-S 會(huì)添加到 dependencies
        • --save-dev 也會(huì)添加到 devDependencies
        • --save 會(huì)添加到 dependencies
        • npm 5.x開始,如果什么參數(shù)都不帶,那么默認(rèn)添加到 dependencies
        ??#?添加到?devDependencies
        ??npm?install?-D?xxxx
        ??#?添加到?dependencies
        ??npm?install?-S?xxxx

        bin

        ?"bin":?{
        ????"vm2":?"./bin/vm2"
        ??},

        bin 字段指定了各個(gè)內(nèi)部命令對(duì)應(yīng)的可執(zhí)行文件的位置。如果全局安裝模塊報(bào),npm 會(huì)使用符號(hào)鏈接把可執(zhí)行文件鏈接到 /usr/local/bin,如果項(xiàng)目中安裝,會(huì)鏈接到 ./node_modules/.bin/。

        上面的這種當(dāng)你的包安裝到全局時(shí):npm 會(huì)在 /usr/local/bin 下創(chuàng)建一個(gè)以 vm2 為名字的軟鏈接,指向全局安裝下來的 vm2 包下面的 "./bin/index.js"。這時(shí)你在命令行執(zhí)行 vm2 則會(huì)調(diào)用鏈接到的這個(gè) js 文件。

        main

        一個(gè)常用的npm包

        {
        ??"main":?"lib/index.js",
        }

        main 屬性指定程序的主入口文件,其他項(xiàng)目在引用這個(gè) npm 包時(shí),實(shí)際上引入的是 lib/index 中暴露出去的模塊。

        npm script(本文重點(diǎn))

        npm script 工作中應(yīng)用到的一個(gè)場(chǎng)景,決定看一下原理。

        什么是 npm script 腳本?

        在生成的 package.json 文件中,有一個(gè) scripts 對(duì)象,在這個(gè)對(duì)象中,npm 允許使用 scripts 字段定義腳本命令。

        "scripts":?{
        ????"test":?"test.js"
        ????"build":?"tsc",
        ??},

        scripts 對(duì)象中每一個(gè)屬性,對(duì)應(yīng)一段腳本。比如,test 命令對(duì)應(yīng)的腳本是 node test.js。

        命令行下使用 npm run 命令,就可以執(zhí)行這段腳本。

        查看當(dāng)前項(xiàng)目的所有 npm 腳本命令,可以使用不帶任何參數(shù)的npm run命令。

        原理

        我們每次在運(yùn)行 scripts 中的一個(gè)屬性時(shí)候(npm run),**實(shí)際系統(tǒng)都會(huì)自動(dòng)新建一個(gè)shell(一般是Bash),在這個(gè)shell里面執(zhí)行指定的腳本命令。因此 凡是能在 shell 中允許的腳本,都可以寫在npm scripts中。

        特別的點(diǎn),npm run 新建的 shell,會(huì)在當(dāng)前目錄的 node_modules/.bin 子目錄加入到 PATH 變量,執(zhí)行結(jié)束后,再將 PATH 變量恢復(fù)原樣。也就是說,當(dāng)前項(xiàng)目目錄 node——modules/.bin 子目錄中所有的腳本,都可以直接用腳本名稱調(diào)用,不需要增加路徑.(簡(jiǎn)單總結(jié):通過 npm 啟動(dòng)的腳本,會(huì)默認(rèn)把 node_modules/.bin 加到 PATH 環(huán)境變量中。)

        例子

        當(dāng)前項(xiàng)目的依賴?yán)锩嬗?Mocha,只要直接寫 mocha test 就可以了。

        "test":?"mocha?test"

        而不用寫成下面這樣。

        "test":?"./node_modules/.bin/mocha?test"

        然后我們就可以直接執(zhí)行 npm run test 了。npm 腳本的退出碼,也遵守 Shell 腳本規(guī)則。如果退出碼不是0,npm 就認(rèn)為這個(gè)腳本執(zhí)行失敗。

        這里有的小伙伴可能會(huì)有疑問,node_modules目錄下的.bin文件是哪里來的?我之前也有這樣的疑問,打開了一個(gè) .bin/tsc,里面的內(nèi)容是這樣的

        #!/usr/bin/env?node
        require('../lib/tsc.js')

        npm install 安裝的某個(gè)模塊,如果模塊在 package.json 中配置了 bin 屬性,在安裝時(shí)候會(huì)自動(dòng)軟鏈接到 node_modules/.bin 中,舉個(gè)例子:如 mocha 源碼 配置了:

        {
        ????"name":"mocha",
        ????"bin":{
        ????????"mocha":"./bin/mocha"
        ????}
        }

        腳本默認(rèn)值

        正常情況下,npm 腳本是用戶自己定義。但是 npm 本身對(duì)兩個(gè)腳本提供了默認(rèn)值,這兩個(gè)腳本不用在 script 屬性中定義,可以直接使用

        "start":?"node?server.js"
        "install":?"node-gyp?rebuild"
        • npm run start 的默認(rèn)值是 node server.js ,前提是根目錄下有 server.js 這個(gè)腳本
        • npm run install 的默認(rèn)值是 node-gyp rebuild,前提是根目錄下有 binding.gyp 文件

        擴(kuò)展小知識(shí),本文不重點(diǎn)說,node-gyp 是什么,binding.gyp 文件是什么?GYP 是一種構(gòu)建自動(dòng)化工具。

        • node-gyp:node 下的 gyp。npm 為了方便直接源碼分發(fā),用戶裝的時(shí)候需要自己進(jìn)下編譯,我們?cè)陂_發(fā) node 程序中需要調(diào)用一些其他語(yǔ)言編寫的工具甚至 dll,這時(shí)候需要先編譯下其他語(yǔ)言,否則會(huì)出現(xiàn)跨平臺(tái)的問題。node-gyp 是用來編譯原生 C++ 模塊的,也可以編寫自己寫的 C++文件,node-gyp 在較新的 Node 版本中都是自帶的,而且是最先版本。
        • gyp 文件:當(dāng) Node.js 項(xiàng)目中有需要和 C++ 交互的需求時(shí),項(xiàng)目的根目需要?jiǎng)?chuàng)建 binging.gyp 文件,每個(gè).gyp 文件都描述了如何去構(gòu)建項(xiàng)目,每個(gè).gyp文件都描述了如何去構(gòu)建項(xiàng)目,gyp文件的語(yǔ)法是 Python數(shù)據(jù)格式(Json格式),配置中數(shù)據(jù)是鍵-值對(duì)的形式。

        看一段簡(jiǎn)單的 .gyp 文件,應(yīng)該好理解一些。

        {
        ????"targets":?[
        ????????{
        ????????????"target_name":?"nodecat",
        ????????????"sources":?[
        ????????????????"src/nodecat.cc",
        ????????????],
        ????????????"include_dirs":?[
        ????????????????"include"
        ????????????],
        ????????????"libraries":?[
        ????????????????"-lcatclient"
        ????????????]
        ????????}
        ????]
        }

        想了解更多詳細(xì)的可以看下面的文檔。

        binging.gyp 參數(shù)說明書/文檔/指南(國(guó)外的一篇文檔抄錄,棒!)binging.gyp 參數(shù)說明書/文檔/指南

        關(guān)于 node-gypbinding.gyp 后面會(huì)單獨(dú)寫一篇文章,這里先簡(jiǎn)單介紹,小伙伴們了解下。

        鉤子(生命周期)

        好多語(yǔ)言或者框架我們學(xué)的時(shí)候都會(huì)考慮到生命周期,其實(shí) package.json 中的 script 也是有生命周期的。npm 腳本有兩個(gè)鉤子,prepost,當(dāng)我們執(zhí)行start腳本時(shí)候,start 的鉤子就是 prestartpoststart。

        當(dāng)我們執(zhí)行 npm run start 的時(shí)候,npm 會(huì)自動(dòng)按照下面的順序執(zhí)行

        npm?run?prestart?&&?npm?run?start?&&?npm?run?poststart

        那這個(gè)鉤子有什么用呢,在實(shí)際開發(fā)中,我們可以做一些準(zhǔn)備或者清理工作,下面是個(gè)例子(引用的阮一峰老師文章中的例子)

        "clean":?"rimraf?./dist?&&?mkdir?dist",
        "prebuild":?"npm?run?clean",
        "build":?"cross-env?NODE_ENV=production?webpack"

        鉤子好用,但是不可亂用,舉個(gè)開發(fā)過程中遇到的坑,有一次想設(shè)置運(yùn)行時(shí)的環(huán)境變量,當(dāng)時(shí)想優(yōu)雅一點(diǎn),就在 prestart 里面設(shè)置了一個(gè)環(huán)境變量,但是在項(xiàng)目 start 的時(shí)候,無法拿到設(shè)置的環(huán)境變量,因?yàn)?script 的屬性運(yùn)行的時(shí)候都會(huì)新啟動(dòng)一個(gè) shell,所以在 prestart中設(shè)置的環(huán)境變量只對(duì)應(yīng)了那個(gè)shell的運(yùn)行時(shí)。

        env 環(huán)境變量

        我們?cè)趫?zhí)行 npm run 腳本時(shí)候, npm 會(huì)設(shè)置一些特殊的env環(huán)境變量。其中package.json中的所有字段,都會(huì)被設(shè)置為以npm_package_開頭的環(huán)境變量。看個(gè)簡(jiǎn)單的例子

        {
        ??"name":?"npm-demo",
        ??"version":?"1.0.0",
        ??"script":?{
        ????"build":?"webpack?--mode=production"
        ??},
        ??"files":?["src"]
        }

        可以得到 npm_package_name、npm_package_version、npm_package_script_build、npm_package_files_0等變量。注意上面 package.json 中對(duì)象和數(shù)組中每個(gè)字段都會(huì)有對(duì)應(yīng)的環(huán)境變量。

        同時(shí),npm 相關(guān)的所有配置也會(huì)被設(shè)置為以npm_config_開頭的環(huán)境變量。此外,還會(huì)設(shè)置一個(gè)比較特殊的環(huán)境變量npm_lifecycle_event,表示正在運(yùn)行的腳本名稱。比如執(zhí)行npm run serve 的時(shí)候,process.env.npm_lifecycle_event值為serve,通過判斷這個(gè)變量,可以將一個(gè)腳本使用在不同的npm scripts中。這里還要提一下上面說的鉤子,npm_lifecycle_event可以和鉤子配合使用,利用這個(gè)變量,在同一個(gè)腳本文件里面,為不同的 npm scripts 命令編寫代碼。請(qǐng)看下面的例子。

        const?TARGET?=?process.env.npm_lifecycle_event;

        if?(TARGET?===?'service')?{
        ??console.log(`Running?the?service?task!`);
        }

        if?(TARGET?===?'preservice')?{
        ??console.log(`Running?the?preservice?task!`);
        }

        if?(TARGET?===?'postservice')?{
        ??console.log(`Running?the?postservice?task!`);
        }

        強(qiáng)調(diào):這些環(huán)境變量只能在 npm run 的腳本執(zhí)行環(huán)境內(nèi)拿到,正常執(zhí)行的 node 腳本是獲取不到的。所以,不能直接通過 env $npm_package_name 的形式訪問,但可以在 scripts 中定義腳本"scripts": {"bundle": "echo $npm_package_name"}來訪問。

        環(huán)境變量常用小技巧

        1. env 命令可以列出所有環(huán)境變量
        npm?run?env
        1. 在shell腳本中輸出環(huán)境變量
        echo?PATH
        1. 在 shell 腳本設(shè)置環(huán)境變量
        echo?PATH?=?/usr/local/lib

        有的時(shí)候我們需要設(shè)置的環(huán)境變量是相對(duì)項(xiàng)目的 再補(bǔ)充一個(gè)shell腳本中設(shè)置環(huán)境變量時(shí)候如何拼接相對(duì)路徑

        echo?PATH?=?${pwd}/lib/include??//使用${},也可以直接使用雙引號(hào)

        腳本傳入?yún)?shù)

        說到腳本傳入?yún)?shù),需要再次提到前面說的 pacakge.json 中的 bin 字段,bin 字段指定了各個(gè)內(nèi)部命令對(duì)應(yīng)的可執(zhí)行文件的位置。前面已經(jīng)說了 bin 文件的產(chǎn)生,有了 bin 字段,在安裝這個(gè)模塊的時(shí)候,node_modules 下面的 .bin/文件夾 下會(huì)有對(duì)應(yīng)模塊的文件,和模塊中的文件相同,然后我們就可以通過調(diào)用這個(gè)文件腳本中的方法傳入?yún)?shù)了。

        在我的 node_module 中找到一個(gè)簡(jiǎn)單 .bin/文件 下的腳本,大家感受一下。

        #!/usr/bin/env?node
        'use?strict';
        var?pkg?=?require('./package.json');
        var?osName?=?require('./');
        var?argv?=?process.argv;

        function?help()?{
        ?console.log([
        ??'',
        ??'??'?+?pkg.description,
        ??'',
        ??'??Example',
        ??'????os-name',
        ??'????OS?X?Mavericks'
        ?].join('\n'));
        }

        if?(argv.indexOf('--help')?!==?-1)?{
        ?help();
        ?return;
        }

        if?(argv.indexOf('--version')?!==?-1)?{
        ?console.log(pkg.version);
        ?return;
        }

        console.log(osName());

        node 處理 scripts 中的參數(shù),除了屬性后面的第一個(gè)命令,以空格分割的任何字符串(除特別shell語(yǔ)法)都是參數(shù),并且都能通過 process.argv 屬性訪問。

        process.argv 屬性返回一個(gè)數(shù)組,數(shù)組包含了啟動(dòng) node 進(jìn)程時(shí)的命令行參數(shù)。第一個(gè)元素為啟動(dòng) node 進(jìn)程的可執(zhí)行文件的絕對(duì)路徑名 process.execPath,第二個(gè)元素為當(dāng)前執(zhí)行的 jacascript 文件路徑。剩余的元素為其他命令行參數(shù)。

        如下 script 例子

        "scripts":{
        ??"serve":?"vue-cli-service?serve?--mode=dev?--mobile?-config?build/example.js"
        }

        當(dāng)我們執(zhí)行 npm run server 命令的時(shí)候,process.argv 的具體內(nèi)容為:

        [?'/usr/local/Cellar/node/12.14.1/bin/node',
        ??'/Users/mac/Vue-projects/hao-cli/node_modules/.bin/vue-cli-service',
        ??'serve',
        ??'--mode=dev',
        ??'--mobile',
        ??'-config',
        ??'build/example.js']

        再列舉幾個(gè)傳參可能有的方式

        npm?run?serve?--params??//?參數(shù)params將轉(zhuǎn)化成process.env.npm_config_params?=?true
        npm?run?serve?--params=123?//?參數(shù)params將轉(zhuǎn)化成process.env.npm_config_params?=?123
        npm?run?serve?-params??//?等同于--params參數(shù)

        npm?run?serve?--?--params??//?將--params參數(shù)添加到process.env.argv數(shù)組中
        npm?run?serve?params??//?將params參數(shù)添加到process.env.argv數(shù)組中
        npm?run?serve?--?params??//?將params參數(shù)添加到process.env.argv數(shù)組中

        對(duì)比下 npm install koa2 --save 是不是知道了bin腳本中接收到的 process.env.npm_config_save = true; 我想是這樣的,有興趣的小伙伴去看源碼驗(yàn)證下。

        執(zhí)行順序

        npm 腳本執(zhí)行多任務(wù)分為兩種情況

        • 并行任務(wù)(同時(shí)的平行執(zhí)行),使用&符號(hào)
        $?npm?run?script1.js?&?npm?run?script2.js
        • 串行任務(wù)(前一個(gè)任務(wù)成功,才執(zhí)行下一個(gè)任務(wù)),使用 && 符號(hào)
        $?npm?run?script1.js?&&?npm?run?script2.js

        任意腳本

        我們配置的腳本命令,如 "start": "node test.js",node test.js 會(huì)當(dāng)做一行代碼傳遞給系統(tǒng)的 shell 去解釋執(zhí)行。實(shí)際使用的 shell 可能會(huì)根據(jù)系統(tǒng)平臺(tái)而不同,類 UNIX 系統(tǒng)里,如 macOSlinux 中指代的是 /bin/sh, 在 windows 中使用的是 cmd.exe。原理我們也看了,因?yàn)榻唤o shell 去解釋執(zhí)行的,說明配置的腳本可以是任意能夠在 shell 中運(yùn)行的命令,而不僅僅是 node 腳本或者 js 代碼。如果你的系統(tǒng)里安裝了 python(或者說系統(tǒng)變量 PATH里能找到 python 命令),你也可以將 scripts 配置為 "myscript": "python xxx.py"

        npm 配置

        npm 的配置操作可以幫助我們預(yù)先設(shè)定好npm對(duì)項(xiàng)目的行為動(dòng)作,也可以讓我們預(yù)先定義好一些配置項(xiàng)以供項(xiàng)目中使用。所以了解npm的配置機(jī)制也是很有必要。

        npm config

        npm cli 提供了 npm config 命令進(jìn)行 npm 相關(guān)配置,通過 npm config ls -l 可查看 npm 的所有配置,包括默認(rèn)配置。npm 文檔頁(yè)為每個(gè)配置項(xiàng)提供了詳細(xì)的說明 https://docs.npmjs.com/misc/config . 修改配置的命令為 npm config set, 我們使用相關(guān)的常見重要配置:

        • proxy, https-proxy: 指定 npm 使用的代理
        • registry 指定 npm 下載安裝包時(shí)的源,默認(rèn)為 https://registry.npmjs.org/ 可以指定為私有 Registry
        • package-lock 指定是否默認(rèn)生成 package-lock 文件,建議保持默認(rèn) true
        • save true/false 指定是否在 npm install 后保存包為 dependencies, npm 5 起默認(rèn)為 true

        刪除指定的配置項(xiàng)命令為 npm config delete .

        這里最常見的一個(gè)操作是 npm 太慢,設(shè)置淘寶鏡像

        npm config set registry https://registry.npm.taobao.org

        恢復(fù)使用之前的 npm

        npm config set registry https://registry.npmjs.org

        env 環(huán)境變量

        如果env環(huán)境變量中存在以npm_config_為前綴的環(huán)境變量,則會(huì)被識(shí)別為npm的配置屬性。比如在env環(huán)境變量中設(shè)置npm_config_package_lock變量:

        export?npm_config_package_lock=false?//修改的是內(nèi)存中的變量,只對(duì)當(dāng)前終端有效

        這時(shí)候執(zhí)行npm installnpm會(huì)從環(huán)境變量中讀取到這個(gè)配置項(xiàng),從而不會(huì)生成package-lock.json文件。

        查看某個(gè)環(huán)境變量:echo $NODE_ENV 刪除某個(gè)環(huán)境變量:unset NODE_ENV

        npmrc 文件

        除了使用 CLInpm config 命令顯示更改 npm 配置,還可以通過 npmrc 文件直接修改配置。

        這樣的 npmrc 文件優(yōu)先級(jí)由高到低包括:

        • 工程內(nèi)配置文件: /path/to/my/project/.npmrc
        • 用戶級(jí)配置文件: ~/.npmrc
        • 全局配置文件: $PREFIX/etc/npmrc (即npm config get globalconfig 輸出的路徑)
        • npm內(nèi)置配置文件:/path/to/npm/npmrc

        很多時(shí)候我們?cè)诠緝?nèi)網(wǎng)需要通過代理才能訪問npm源,通過這個(gè)機(jī)制,我們可以方便地在工程跟目錄創(chuàng)建一個(gè) .npmrc 文件來共享需要在團(tuán)隊(duì)間共享的 npm 運(yùn)行相關(guān)配置。比如如果我們?cè)诠緝?nèi)網(wǎng)環(huán)境下需通過代理才可訪問 registry.npmjs.org 源,或需訪問內(nèi)網(wǎng)的 registry, 就可以在工作項(xiàng)目下新增 .npmrc 文件并提交代碼庫(kù)。

        proxy?=?http://proxy.example.com/
        https-proxy?=?http://proxy.example.com/
        registry?=?http://registry.example.com/

        因?yàn)轫?xiàng)目級(jí) .npmrc 文件的作用域只在本項(xiàng)目下,所以在非本目錄下,這些配置并不生效。對(duì)于使用筆記本工作的開發(fā)者,可以很好地隔離公司的工作項(xiàng)目、在家學(xué)習(xí)研究項(xiàng)目?jī)煞N不同的環(huán)境。

        將這個(gè)功能與 ~/.npm-init.js 配置相結(jié)合,可以將特定配置的 .npmrc.gitignore, README 之類文件一起做到 npm init 腳手架中,進(jìn)一步減少手動(dòng)配置。

        npm 包發(fā)布

        規(guī)范的 npm 模塊目錄

        一個(gè) node.js 模塊是基于 CommonJS 模塊化規(guī)范實(shí)現(xiàn)的,嚴(yán)格按照 CommonJS 規(guī)范,模塊目錄下除了必須包含包描述文件 package.json 以外,還需要包含以下目錄:

        • bin:存放可執(zhí)行二進(jìn)制文件的目錄
        • lib:存放js代碼的目錄
        • doc:存放文檔的目錄
        • test:存放單元測(cè)試用例代碼的目錄

        如何寫好一個(gè)模塊的 README 文件

        這里不單獨(dú)寫,推薦一篇不錯(cuò)的討論

        https://www.zhihu.com/question/29100816

        如何發(fā)布自己的 npm 包

        1. 先去 npm 注冊(cè)個(gè)賬號(hào),然后在命令行使用
        npm?adduser?#根據(jù)提示輸入用戶名密碼即可
        1. 使用命令發(fā)布你的包

        在推送之前,可以通過配置一個(gè) .npmignore 文件來排除一些文件, 防止大量的垃圾文件推送到 npm, 規(guī)則上和你用的 .gitignore 是一樣的。.gitignore 文件也可以充當(dāng) .npmignore 文件

        npm?publish
        1. 發(fā)布成功之后,你就可以像下載安裝其他包一樣使用你自己的開發(fā)工具了
        npm?install?koalanpmstudy

        關(guān)于 npm 包的更新

        更新 npm 包也是使用 npm publish 命令發(fā)布,不過必須更改 npm 包的版本號(hào),即 package.json 的 version 字段,否則會(huì)報(bào)錯(cuò),同時(shí)我們應(yīng)該遵 Semver(語(yǔ)義化版本號(hào)) 規(guī)范,npm 提供了 npm version 給我們升級(jí)版本

        #?升級(jí)補(bǔ)丁版本號(hào)
        $?npm?version?patch

        #
        ?升級(jí)小版本號(hào)
        $?npm?version?minor

        #
        ?升級(jí)大版本號(hào)
        $?npm?version?major

        本地開發(fā)的 npm 包如何調(diào)試

        在本地開發(fā)的模塊包的時(shí)候,可以使用 npm link 調(diào)試,將模塊鏈接到對(duì)應(yīng)的運(yùn)行項(xiàng)目中去,方便地對(duì)模塊進(jìn)行調(diào)試和測(cè)試。具體使用步驟如下

        • 假如我的項(xiàng)目是 koalaNpmStudy,假如我的 npm 模塊包名稱是 npm-ikoala
        • 進(jìn)入到 模塊包 npm-ikoala 目錄中,執(zhí)行 npm link
        • 在自己的項(xiàng)目 koalaNpmStudy 中創(chuàng)建連接執(zhí)行 npm link npm-ikoala
        • 在自己項(xiàng)目的 node_module 中會(huì)看到鏈接過來的模塊包,然后就可以像使用其他的模塊包一樣使用它了。
        • 調(diào)試結(jié)束后可以使用 npm unlink 取消關(guān)聯(lián)

        npm link 主要做了兩件事:

        1. 為目標(biāo) npm 模塊創(chuàng)建軟鏈接,將其鏈接到全局 node 模塊安裝路徑 /usr/local/lib/node_modules/。
        2. 為目標(biāo) npm 模塊的可執(zhí)行 bin 文件創(chuàng)建軟鏈接,將其鏈接到全局 node 命令安裝路徑 /usr/local/bin/。

        總結(jié)

        本文對(duì) npm 相關(guān)的內(nèi)容進(jìn)行了一個(gè)梳理,npm install 原理以及和 npm 與yarn 的區(qū)別沒有講,會(huì)在下一篇文章進(jìn)行講解。希望本文看完對(duì)小伙伴們有幫助。

        歡迎關(guān)注「前端雜貨鋪」,一個(gè)有溫度且致力于前端分享的雜貨鋪

        關(guān)注回復(fù)「加群」,可加入雜貨鋪一起交流學(xué)習(xí)成長(zhǎng)

        “在看轉(zhuǎn)發(fā)”是最大的支持

        參考文章

        • https://juejin.im/post/5cb3f1ef5188256d917874ff
        • https://www.ruanyifeng.com/blog/2016/10/npm_scripts.html
        • https://zhuanlan.zhihu.com/p/23493436
        • https://juejin.im/post/5ab3f77df265da2392364341#heading-22
        • https://www.cnblogs.com/nanvann/p/3913880.html
        瀏覽 41
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            香港三日三级少妇三级99 | 四虎免费在线观看 | 黄色综合 | 亚洲中文字幕无码爆乳av | 懂色Av懂色Aⅴ精彩AV | 台湾美女三级写真hd在线观看 | 国产麻豆91 | 亚洲精品h | 波多野结衣av一区二区蜜桃观看 | 国产精品美女久久久久久久网站 |