<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          寫一個(gè)包并發(fā)布到 npm 上面

          共 17194字,需瀏覽 35分鐘

           ·

          2022-07-11 17:51

          image.png

          說到npm包都會(huì)給人一種特別高大上的感覺,并且自己寫了一個(gè)包之后如果有人用那么就會(huì)產(chǎn)生莫大的成就感,程序員的快樂就是這么簡單。

          想必有產(chǎn)生寫npm包想法的人都對(duì)模塊化比較熟悉,并且對(duì)于react、vue兩者之一都比較熟練了。

          下面呢我們就是使用react來寫一個(gè)自己的npm包,我們呢會(huì)使用自己封裝的webpack腳手架來寫,如果有興趣同學(xué)可以來看一下我的自我沉淀webpack5+react+eslint+tslint[1]文章。接下來的內(nèi)容呢也是基于此來說明的。

          這里也有現(xiàn)成的腳手架[2]

          一、不同點(diǎn)

          npm包的目錄結(jié)構(gòu)和普通的腳手架結(jié)構(gòu)有所不同

          1.啟動(dòng)目錄不同:以往我們習(xí)慣將entry文件寫在src中,但是npm包的入口文件不能寫在src中,因?yàn)閚pm是將我們的源代碼打包,不可以包括html。

          所以將index.jsx和index.html文件提取到example文件中?!咀⒁狻縠xample文件要和src同級(jí)。

          結(jié)構(gòu)和內(nèi)容如下

          index.jsx

           import React from 'react';
           import { render } from 'react-dom';
           import ReactDemo from '../src';

           const App = () => <ReactDemo />;
           render(<App />document.getElementById('root'));

          index.html

           <!DOCTYPE html>
           <html lang="en">
             <head>
               <meta charset="UTF-8" />
               <meta http-equiv="X-UA-Compatible" content="IE=edge" />
               <meta name="viewport" content="width=device-width, initial-scale=1.0" />
               <title>Document</title>
             </head>
             <body>
               <div id="root"></div>
             </body>
           </html>

          然后在src/index.jsx文件中 導(dǎo)出

           import App1 from './App';
           export default App1;
              

          二 配置npm包的打包運(yùn)行文件

          在 config文件夾中新建webpack.npm.js文件

          配置文件內(nèi)容差不多。如下:詳細(xì)配置請(qǐng)移步 自我沉淀webpack5+react+eslint+tslint[3]

          externals劃重點(diǎn):這個(gè)可以告訴npm打包的時(shí)候不許將下面幾種東西打包進(jìn)去哦。

           const { resolve } = require('path');
           const cssLoaders = [
             'style-loader',
             {
               loader'css-loader',
               options: {
                 importLoaders1,
                 modules: {
                   auto(resourcePath) => resourcePath.endsWith('.less'),
                   localIdentName'[local]_[hash:base64:10]',
                 },
               },
             },
             {
               loader'postcss-loader',
               options: {
                 postcssOptions: {
                   plugins: [['autoprefixer'], require('postcss-preset-env')()],
                 },
               },
             },
           ];
           module.exports = {
             entry'./src/index.tsx',
             mode: process.env.NODE_ENV,
             externals: {
               antd'antd',
               react'React',
             },
             output: {
               libraryTarget'umd',
               filename'index.js',
               path: resolve(resolve(__dirname, '..'), 'dist'),
               cleantrue,
             },
             resolve: {
               alias: {
                 '@': resolve(resolve(__dirname, '..'), 'src/'),
               },
               extensions: ['.ts''.tsx''.js''.jsx''.json'],
               mainFiles: ['index'],
             },

             devServer: {
               hottrue,
               port3002,
               host'127.0.0.1',
               compresstrue,
               opentrue,
               proxy: {
                 '/api': {
                   target'http://127.0.0.1:3002',
                   pathRewrite: { '^/api''' },
                   securefalse,
                 },
               },
             },

             module: {
               rules: [
                 {
                   test/\.(js|jsx)$/,
                   include: resolve(resolve(__dirname, '..'), ''),
                   exclude/node_modules/,
                   enforce'pre',
                   use: [
                     {
                       loader'babel-loader',
                       options: {
                         presets: ['@babel/preset-env''@babel/preset-react'],
                         // 緩存:第二次構(gòu)建時(shí),會(huì)讀取之前的緩存
                         cacheDirectorytrue,
                       },
                     },
                   ],
                 },
                 {
                   test/\.tsx$/,
                   loader'ts-loader',
                   exclude/node_modules/,
                 },
                 {
                   test/\.css$/,
                   use: [...cssLoaders],
                 },
                 {
                   test/\.less$/,
                   use: [...cssLoaders, 'less-loader'],
                 },
                 {
                   test/\.s[ac]ss$/,
                   use: [...cssLoaders, 'sass-loader'],
                 },
                 {
                   exclude/.(html|less|css|sass|js|jsx|ts|tsx)$/,
                   test/\.(jpg|jpe|png|gif)$/,
                   loader'file-loader',
                   options: {
                     name'imgs/[name].[ext]',
                     outputPath'other',
                   },
                 },
                 {
                   test/\.(ect|ttf|svg|woff)$/,
                   use: {
                     loader'file-loader',
                     options: {
                       name'icon/[name].[ext]',
                     },
                   },
                 },
               ],
             },
           };

          下面著重說一下package.json中的內(nèi)容

          • name: 包名,后續(xù)在npm中搜索全靠它

          • version:版本號(hào),每發(fā)布一次npm包就要增加一個(gè)版本,每個(gè)版本不能重復(fù)。

          • description:描述

          • main: 本包向外暴露的文件,很重要,一定要和你打包出來的文件名一模一樣,我的叫做"dist/index.js"

          • private: true/false 是否為私有。一般為false否則只有自己能使用

          • flies: 暴露的文件夾, 有哪些文件夾提交到npm上面 格式為[ "dist" ]

          • keywords: npm檢索的關(guān)鍵字

          • author: 作者

          • license: ISC

          • peerDependencies: 代表著當(dāng)前npm包依賴下面這幾種環(huán)境。

            完整配置

             {
              "name""new_webpack_action2",
              "version""1.0.24",
              "m""",
              "main""dist/index.js",
              "private"false,
              "flies": [
                "dist"
              ],
              "scripts": {
                "test""echo \"Error: no test specified\" && exit 1",
                "dev""export NODE_ENV=development && npx webpack serve --config config/webpack.dev.js",
                "build""export NODE_ENV=production && npx webpack   --config config/webpack.prod.js",
                "npm""export NODE_ENV=production && npx webpack   --config config/webpack.npm.js"
              },
              "keywords": [
                "react",
                "javascript",
                "npm"
              ],
              "author""[email protected]",
              "license""ISC",
              "devDependencies": {
                "@ant-design/icons""4.7.0",
                "@babel/core""^7.15.0",
                "@babel/preset-env""^7.15.0",
                "@babel/preset-react""^7.14.5",
                "@types/lodash""^4.14.178",
                "@types/react""^17.0.19",
                "@types/react-dom""^17.0.11",
                "@types/react-router-dom""^5.3.3",
                "@typescript-eslint/eslint-plugin""^5.11.0",
                "@typescript-eslint/parser""^5.11.0",
                "autoprefixer""^10.3.2",
                "babel-loader""^8.2.2",
                "babel-plugin-import""^1.13.3",
                "css-loader""^6.2.0",
                "css-minimizer-webpack-plugin""^3.0.2",
                "eslint""^8.8.0",
                "eslint-config-airbnb""^19.0.4",
                "eslint-plugin-import""^2.25.4",
                "eslint-plugin-jsx-a11y""^6.5.1",
                "eslint-plugin-react""^7.28.0",
                "eslint-plugin-react-hooks""^4.3.0",
                "eslint-webpack-plugin""^3.1.1",
                "file-loader""^6.2.0",
                "html-webpack-externals-plugin""^3.8.0",
                "html-webpack-plugin""^5.5.0",
                "less""^4.1.1",
                "less-loader""^10.0.1",
                "lodash""^4.17.21",
                "mini-css-extract-plugin""^2.2.0",
                "postcss-loader""^6.1.1",
                "postcss-preset-env""^7.4.2",
                "sass""^1.38.0",
                "sass-loader""^12.1.0",
                "speed-measure-webpack-plugin""^1.5.0",
                "style-loader""^3.2.1",
                "stylelint""^13.13.1",
                "stylelint-config-standard""^22.0.0",
                "terser-webpack-plugin""^5.1.4",
                "thread-loader""^3.0.4",
                "ts-loader""^9.2.5",
                "tslint""^6.1.3",
                "typescript""^4.5.5",
                "webpack""^5.68.0",
                "webpack-cli""^4.8.0",
                "webpack-dev-server""^4.0.0",
                "webpack-merge""^5.8.0",
                "workbox-webpack-plugin""^6.4.2"
              },
              "dependencies": {
                "antd""4.18.8",
                "axios""^0.26.0",
                "react""17.0.2",
                "react-dom""17.0.2",
                "react-router-dom""5.2.0"
              },
              "peerDependencies": {
                "@ant-design/icons""4.7.0",
                "antd""4.18.8",
                "bizcharts""4.1.15",
                "rc-footer""0.6.6",
                "react""17.0.2",
                "react-dom""17.0.2",
                "react-router-dom""5.2.0"
              },
              "browserslist": {
                "development": [
                  "last 1 chrome version",
                  "last 1 firefox version",
                  "last 1 safari version"
                ],
                "production": [
                  ">0.2%",
                  "not dead",
                  "not op_mini all"
                ]
              }
            }

          三、發(fā)布

          如果是第一次發(fā)布包,執(zhí)行以下命令,然后輸入前面注冊(cè)好的NPM賬號(hào),密碼和郵箱,將提示創(chuàng)建成功

          npm adduser

          如果不是第一次發(fā)布包,執(zhí)行以下命令進(jìn)行登錄,同樣輸入NPM賬號(hào),密碼和郵箱

          npm login

          注意:npm adduser成功的時(shí)候默認(rèn)你已經(jīng)登陸了,所以不需要再進(jìn)行npm login了

          接著先進(jìn)入項(xiàng)目文件夾下,然后輸入以下命令進(jìn)行發(fā)布

          npm publish

          當(dāng)終端顯示如下面的信息時(shí),就代表版本號(hào)為1.0.0(你的package.json中的版本號(hào))的包發(fā)布成功啦!前往NPM官網(wǎng)就可以查到你的包

          + 你的文件名@0.1.0

          四、報(bào)錯(cuò)

          1、如果出現(xiàn)

          npm ERR! code E403
          npm ERR! 403 403 Forbidden - PUT https://registry.npmjs.org/ghost-watermarkdemo - Forbidden
          npm ERR! 403 In most cases, you or one of your dependencies are requesting
          npm ERR! 403 a package version that is forbidden by your security policy, or
          npm ERR! 403 on a server you do not have access to.

          以下幾種原因會(huì)導(dǎo)致

          賬號(hào)密碼錯(cuò)誤   (請(qǐng)檢查npm官網(wǎng)的賬號(hào)密碼)
          包重名     (請(qǐng)檢查npm官網(wǎng)上是否有同名項(xiàng)目,名字取決于 package.js 的項(xiàng)目名字段)
          網(wǎng)絡(luò)原因   
          鏡像源問題 
          新注冊(cè)的用戶郵箱未激活。  登陸你的郵箱去激活(如下)
          image.png

          2、 如果出現(xiàn)

          image.png

          需要在你的package.json中 private改為false或者刪除

          更新已經(jīng)發(fā)布的包

          更新包的操作和發(fā)布包的操作是一樣的

             npm publish

          但是每次更新時(shí),必須修改版本號(hào)后才能更新,比如將1.0.0修改為1.0.1后才能更新發(fā)布。

          這里的包版本管理規(guī)則都是一樣的,采用的是semver(語義化版本),意思就是版本號(hào):大改.中改.小改

          五、## 從npm上面卸載自己發(fā)布的包

          進(jìn)入自己項(xiàng)目的目錄執(zhí)行。npm unpublish --force 出現(xiàn):

             npm WARN using --force Recommended protections disabled.
          -包名@0.1.0

          則卸載成功,這時(shí)在npm上面就搜索不到了

          參考資料

          [1]

          https://juejin.cn/post/7002157698108096543: https://juejin.cn/post/7002157698108096543

          [2]

          https://github.com/ghost-myl/npm-custom_webpack: https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fghost-myl%2Fnpm-custom_webpack

          [3]

          https://juejin.cn/post/7002157698108096543: https://juejin.cn/post/7002157698108096543


          關(guān)于本文

          來自:夏末海棠

          https://juejin.cn/post/7072652104837365774


          最后


          歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
          回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會(huì)很認(rèn)真的解答喲!
          回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
          回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
          如果這篇文章對(duì)你有幫助,在看」是最大的支持
           》》面試官也在看的算法資料《《
          “在看和轉(zhuǎn)發(fā)”就是最大的支持


          瀏覽 48
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品剧情亚洲二区 | 天堂中文资源库 | 黄色视频链接在线观看 | 五月欧美激激激综合网色播 | 免费日韩欧美 |