愿世间充满爱 發表於 2026-3-2 18:01:00

如何在 DotNet 中使用类似 golang 的 vendor 的编译模式

<p><strong><font size="1" color="gray">作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!</font></strong></p>
<ul>
<li><font size="1" color="gray">cnblogs博客</font></li>
<li><font size="1" color="gray">zhihu</font></li>
<li><font size="1" color="gray">Github</font></li>
<li><font size="1" color="gray">公众号:一本正经的瞎扯</font><br>
<img src="https://img2022.cnblogs.com/blog/1457949/202202/1457949-20220216153819145-1193738712.png"></li>
</ul>
<hr>
<p>一个项目中,存在部分库是公司内的,且需要配置个人的用户名和密码连接到 NuGet 站点,才能下载这些库。<br>
而有时候需要直接把一个仓库拉到某个环境上进行编译,且不希望把带了密码的 <code>NuGet.Config</code> 文件提交到代码仓库中。<br>
能不能把公司内的库放到类似 golang 的 vendor 目录下?然后编译机器拉到仓库后就能直接编译,而不再依赖公司的 NuGet 站点了。</p>
<p>下面是我的做法:</p>
<h1 id="下载所有依赖库">下载所有依赖库</h1>
<p>在项目根目录中定义一个配置完整的 NuGet.Config 文件,取名为: <code>NuGet.Config.for.download</code></p>
<h2 id="nugetconfigfordownload">NuGet.Config.for.download</h2>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;configuration&gt;
&lt;packageSources&gt;
    &lt;clear /&gt;
    &lt;add key="nuget.org" value="https://api.nuget.org/v3/index.json" /&gt;
    &lt;add key="Internal" value="https://my.company.com/repository/xxxx/" /&gt;
&lt;/packageSources&gt;

&lt;packageSourceMapping&gt;
    &lt;!-- Private packages should resolve from private feeds --&gt;
    &lt;packageSource key="Internal"&gt;
      &lt;package pattern="MyCompany.*" /&gt;
    &lt;/packageSource&gt;

    &lt;!-- Public packages resolve from nuget.org --&gt;
    &lt;packageSource key="nuget.org"&gt;
      &lt;package pattern="*" /&gt;
    &lt;/packageSource&gt;
&lt;/packageSourceMapping&gt;

&lt;packageSourceCredentials&gt;
    &lt;Internal&gt;
      &lt;add key="Username" value="${USER}" /&gt;
      &lt;add key="ClearTextPassword" value="${PASSWORD}" /&gt;
    &lt;/Internal&gt;
&lt;/packageSourceCredentials&gt;
&lt;/configuration&gt;
</code></pre>
<p>这个文件用于第一次使用时下载库,这个文件不必提交到仓库。</p>
<h2 id="下载所有依赖库-1">下载所有依赖库</h2>
<pre><code class="language-bash">mkdir -p ./vendor/public/
dotnet restore --configfile ./NuGet.Config.for.download --packages ./vendor/public/
</code></pre>
<p>指定配置文件,把所有依赖项下载到 /vendor/public/ 目录。</p>
<p>下载好后,把公司内部的库移动到另一个目录:</p>
<pre><code class="language-bash">rm -fdr ./vendor/private/ ; mkdir -p ./vendor/private/ &amp;&amp; \
        mv ./vendor/public/MyCompany.* ./vendor/private/
</code></pre>
<h1 id="编译">编译</h1>
<h2 id="用于编译的-nugetconfig-配置">用于编译的 NuGet.Config 配置</h2>
<p>新增一个专门用于 vendor 模式的 NuGet.Config 配置文件,取名为:<code>NuGet.Config.vendor</code></p>
<pre><code class="language-xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;configuration&gt;
&lt;packageSources&gt;
    &lt;clear /&gt;
    &lt;add key="nuget.org" value="https://api.nuget.org/v3/index.json" /&gt;
    &lt;add key="Internal" value="./vendor/private/" /&gt;
&lt;/packageSources&gt;

&lt;packageSourceMapping&gt;
    &lt;!-- Private packages should resolve from private feeds --&gt;
    &lt;packageSource key="Internal"&gt;
      &lt;package pattern="MyCompany.*" /&gt;
    &lt;/packageSource&gt;

    &lt;!-- Public packages resolve from nuget.org --&gt;
    &lt;packageSource key="nuget.org"&gt;
      &lt;package pattern="*" /&gt;
    &lt;/packageSource&gt;
&lt;/packageSourceMapping&gt;

&lt;/configuration&gt;

</code></pre>
<h2 id="基于-vendor-目录的-restore">基于 vendor 目录的 restore</h2>
<pre><code class="language-bash">dotnet restore --configfile ./NuGet.Config.vendor -r linux-x64
</code></pre>
<h2 id="编译-1">编译</h2>
<pre><code class="language-bash">dotnet publish MyProj.csproj \
                --no-restore \
                -c Debug -r linux-x64 \
                -o ./build/linux/amd64/
</code></pre>
<p>最关键的参数是 <code>--no-restore</code></p>
<h2 id="docker-中编译">docker 中编译</h2>
<pre><code class="language-bash">docker run --rm\
        --platform linux/amd64 \
        -v "./":/src \
        -w /src/ \
        mcr.microsoft.com/dotnet/sdk:8.0 \
        bash -c ' \
                dotnet restore --configfile ./NuGet.Config.vendor -r linux-x64 &amp;&amp; \
                dotnet publish MyProj.csproj \
                        --no-restore \
                        -c Debug -r linux-x64 \
                        -p:PublishAot=false \
                        -p:PublishSingleFile=false \
                        -p:IncludeNativeLibrariesForSelfExtract=true \
                        -p:EnableCompressionInSingleFile=true \
                        -p:GenerateDocumentationFile=false \
                        -p:StripSymbols=false \
                        -p:DebugType=portable \
                        -p:DebugSymbols=true \
                        -p:EmbedUntrackedSources=true \
                        -p:EmbedAllSources=true \
                        -p:ContinuousIntegrationBuild=true \
                        -p:Optimize=false \
                        -o /src/build/linux/amd64/ \
        '
</code></pre>
<h1 id="提交到-git">提交到 git</h1>
<p><code>.gitignore</code> 文件中增加一些配置:</p>
<pre><code class="language-text">NuGet.Config.for.download# 用于下载的文件,不提交到仓库,里面有密码
/vendor/public/# public 文件太多了,不提交到仓库
!/vendor/private/# 说明这个目录一定要提交
!/vendor/private/**/*nupkg# .nupkg 类型的文件一定要提交
</code></pre>
<hr>
<p>好了,在别的环境 git clone 后,使用上述提到的编译命令行就可以编译了。</p>
<p>希望对你有用, Have fun. 😃</p><br><br>
来源:https://www.cnblogs.com/ahfuzhang/p/19660265
頁: [1]
查看完整版本: 如何在 DotNet 中使用类似 golang 的 vendor 的编译模式