npm发包初步尝试:pc-load-markdwon-image

167 阅读4分钟

学习开发了一个npm小插件,可以在本地的md文档中识别网络图片并下载到本地

使用:

// 安装: npm install pc-load-markdwon-image

// 使用 即可看到效果: pc-load-markdwon-image +文件名

具体开发过程如下

1 初始化项目

npm init -y

成功后配置如下 name不能有大写的

然后再同级目录下增加:index.js

然后执行npm link

作用:链接

建立连接。再当前目录下执行, 把当前目录模块创建成本地依赖包,创建之后出现了packag-lock.json文件

对应接触链接方法: npm unlink npmDemo1

如下图说明执行成功了

直接执行tets1:

2 安装依赖

yarn add axios
yarn add rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs rollup-plugin-terser -D

然后再根目录下兴建rollup.config.js文件用于配置

import { nodeResolve } from '@rollup/plugin-node-resolve' // 用于打包第三方模块
import commonjs from '@rollup/plugin-commonjs' // 将commonjs模块转化为es6模块, 这样rollup才能正常进行解析
import { terser } from 'rollup-plugin-terser' // 压缩打包后的文件
const banner = '#!/usr/bin/env node'

export default {
    input:'./index.js', // 入口文件
    output:{
        export:'auto',
        file:'./dist/index/js', // 打包后的文件
        format:'cjs',
        name:'tset1',
        banner, // 再打包后的文件首行引入,表示此文件可以当做脚本运行,并且可以再node中运行
    },
    plugins:[
        commonjs(),
        nodeResolve({
            preferBuiltins:true, 
        }),
        terser(),
    ]

}

更改package.json文件:

修改前:

{
  "name": "test1",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

修改后:

{
  "name": "test1",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "build": "rollup -c rollup.config.js",
    "dev": "rollup -c rollup.config.js -w"
  },
  "keywords": [],
  "author": "pucai",
  "license": "ISC",
  "bin": {
    "test1": "dist/index.js" 
  }
}

出现报错:

需要再package.json中添加: "type" :"module" ,

注意 修改package.json后需要保存 如果出现冲突需要覆盖

打包之后如图:只有一个js文件

项目搭建如图:

3 业务代码开发

步骤:

  1. 获取 markdown 文件路径
  2. 读取 markdown 文件,获取一串字符串
  3. 正则匹配出所有图片
  4. 下载图片到本地
  5. 替换图片链接为本地路径
  6. 写入 markdown 文件

直接写在index.js中:

// #! /usr/bin/env node
// 在rollup中配置后删除
// /usr/bin/env就是告诉系统可以在PATH目录中查找。 所以配置#!/usr/bin/env node,
// 就是解决了不同的用户node路径不同的问题,可以让系统动态的去查找node来执行你的脚本
// console.log('hello pucai')

// 业务代码
// 1、获取 markdown 文件路径

// 2、读取 markdown 文件,获取一串字符串

// 3、正则匹配出所有图片

// 4、下载图片到本地

// 5、替换图片链接为本地路径

// 6、写入 markdown 文件

const inputPath = process.argv[2] // 获取输入的文件路径

const path = require('path')
const fs = require('fs')
const axios = require('axios')

const mdPath = path.resolve(inputPath) // md文件绝对路径,如:/Users/xxx/Desktop/test.md
let rootPath = '' // 初始化md文件所在目录

// 在md文件所在目录创建images文件夹,保存本地图片
try {
  const { dir } = path.parse(mdPath)
  rootPath = dir
  fs.mkdirSync(`${rootPath}/images`) //创建文件路径
} catch (err) {
  console.log(err.code)
}

main() 

// 主函数
async function main() {
  let content = fs.readFileSync(mdPath, 'utf8') // 同步读取md文件的绝对路径
  const imgList = getImgsByPath(mdPath)
  for (const img of imgList) {
    const { imageName } = await getLocalImgPath(img)
    content = content.replace(img, `./images/${imageName}`)
    fs.writeFileSync(mdPath, content)
  }
}

// 根据文件路径获取所有图片链接
function getImgsByPath(filePath) {
  let content = fs.readFileSync(filePath, 'utf8')
  const pattern = /![(.*?)]((.*?))/gm // 匹配图片正则出所有图片
  const imgList = content.match(pattern) || [] // ![img](http://hello.com/image.png)
  return imgList.map((item) => {
    return item.split('](')[1].slice(0, -1) // http://hello.com/image.png 替换成地址
  })  
}

// 获取本地图片路径,下载图片并保存在images目录
function getLocalImgPath(imgUrl) {
  const fileType = imgUrl.split('.').slice(-1)[0] // 获取图片格式 jpn png
  const imageName = `${new Date().getTime()}${fileType ? `.${fileType}` : ''}` // 加上时间戳 保证图片命名不冲突
  return axios({
    url: imgUrl,
    responseType: 'stream',
    timeout: 10000,
  }).then((response) => {
    return new Promise((resolve, reject) => {
      const imagePath = `${rootPath}/images/${imageName}` // 图片路径
      response.data
        .pipe(fs.createWriteStream(imagePath))
        .on('finish', () => resolve({ imageName, imagePath }))
        .on('error', (e) => reject(e))
    })
  })
}

npm run build 后npm link

打包有可能报错:

产生原因:

  • 默认情况下rollup.js不支持导入json模块

解决方案:

  • 安装@rollup/plugin-json插件

npm install @rollup/plugin-json --save-dev

最后,修改rollup.config.js文件中

import json from '@rollup/plugin-json'

plugins: [
json(),
]

npm link 报错

原因:之前已经链接过 需要删除链接之后再链接 :npm unlink

然后再同级目录下新建一个带有图片链接的test.md

运行 test1 test.md 出现报错:

再打包后我把package.json中的type删除,可以打包成功.

最后结果:

4 发布

接着添加用户、登录、发布到 npm 供其他人使用。

npm adduser
npm login  这两个命令的作用是一样的 登录之后不需要像我一样傻乎乎的再重新登录。
npm whoami  查看本地登录npm 的用户
npm publish
复制代码

遇到报错:

推送成功如图:

下载尝试:

运行成功:

至此已经完成初步开发,当然离完整的npm组件还有很长的路,需要考虑阅读文档,版本管理等问题,后面继续学习。