ps做网站头部,做封面图什么网站,如何删除在凡科上做的网站,微网站开发需要多少钱大家好#xff0c;我是若川。持续组织了8个月源码共读活动#xff0c;感兴趣的可以 点此加我微信ruochuan12 参与#xff0c;每周大家一起学习200行左右的源码#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外… 大家好我是若川。持续组织了8个月源码共读活动感兴趣的可以 点此加我微信ruochuan12 参与每周大家一起学习200行左右的源码共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。历史面试系列。另外目前建有江西|湖南|湖北籍前端群可加我微信进群。本文经作者yuxiaoliang 授权转载原文链接https://juejin.cn/post/7099041402771734559npm是前端开发人员广泛使用的包管理工具项目中通过package.json来管理项目中所依赖的npm包的配置。package.json就是一个json文件除了能够描述项目的包依赖外允许我们使用“语义化版本规则”指明你项目依赖包的版本让你的构建更好地与其他开发者分享便于重复使用。本文主要从最近的实践出发结合最新的npm和node的版本介绍一下package.json中一些常见的配置以及如何写一个规范的package.jsonpackage.jsonpackage.json常用属性package.json环境相关属性package.json依赖相关属性package.json三方属性1package.json1. package.json简介在nodejs项目中package.json是管理其依赖的配置文件通常我们在初始化一个nodejs项目的时候会通过npm init然后在你的目录下会生成3个目录/文件 node_modules, package.json和 package.lock.json。其中package.json的内容为{name: Your project name,version: 1.0.0,description: Your project description,main: app.js,scripts: {test: echo \Error: no test specified\ exit 1,},author: Author name,license: ISC,dependencies: {dependency1: ^1.4.0,dependency2: ^1.5.2}
}上述可以看出package.json中包含了项目本身的元数据,以及项目的子依赖信息(比如dependicies等)。2. package-lock.json我们发现在npm init的时候不仅生成了package.json文件还生成了package-lock.json文件。那么为什么存在package.json的清空下还需要生成package-lock.json文件呢。本质上package-lock.json文件是为了锁版本在package.json中指定的子npm包比如react: ^16.0.0在实际安装中只要高于react的版本都满足package.json的要求。这样就使得根据同一个package.json文件两次安装的子依赖版本不能保证一致。而package-lock文件如下所示子依赖dependency1就详细的指定了其版本。起到lock版本的作用。{name: Your project name,version: 1.0.0,lockfileVersion: 1,requires: true,dependencies: {dependency1: {version: 1.4.0,resolved:
https://registry.npmjs.org/dependency1/-/dependency1-1.4.0.tgz,integrity:
sha512-aUqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA},dependency2: {version: 1.5.2,resolved:
https://registry.npmjs.org/dependency2/-/dependency2-1.5.2.tgz,integrity:
sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6oP2cAgEOOwIxMftr4ZCTI6d551ij9j61DFr0nsP2uQ}}
}2package.json常用属性本章来聊聊package.json中常用的配置属性形如nameversion等属性太过简单不一一介绍。本章主要介绍一下script、bin和workspaces属性。2.1 script在npm中使用script标签来定义脚本每当制定npm run的时候就会自动创建一个shell脚本这里需要注意的是npm run新建的这个 Shell会将本地目录的node_modules/.bin子目录加入PATH变量。这意味着当前目录的node_modules/.bin子目录里面的所有脚本都可以直接用脚本名调用而不必加上路径。比如当前项目的依赖里面有 esbuild只要直接写esbuild xxx 就可以了。{// ...scripts: {build: esbuild index.js,}
}{// ...scripts: {build: ./node_modules/.bin/esbuild index.js }
}上面两种写法是等价的。2.2 binbin属性用来将可执行文件加载到全局环境中指定了bin字段的npm包一旦在全局安装就会被加载到全局环境中可以通过别名来执行该文件。比如\bytepack/cli的npm包bin: {bytepack: ./bin/index.js},一旦在全局安装了bytepack/cli就可以直接通过bytepack来执行相应的命令比如bytepack -v
//显示1.11.0如果非全局安装那么会自动连接到项目的node_module/.bin目录中。与前面介绍的script标签中所说的一致可以直接用别名来使用。2.3 workspaces在项目过大的时候最近越来越流行monorepo。提到monorepo就绕不看workspaces早期我们会用yarn workspaces现在npm官方也支持了workspaces. workspaces解决了本地文件系统中如何在一个顶层root package下管理多个子packages的问题在workspaces声明目录下的package会软链到最上层root package的node_modules中。直接以官网的例子来说明{name: my-project,workspaces: [packages/a]
}在一个npm包名为my-project的npm包中存在workspaces配置的目录。.
-- package.json
-- index.js
-- packages-- a| -- package.json并且该最上层的名为my-project的root包有packages/a子包。此时我们如果npm install,那么在root package中node_modules中安装的npm包a指向的是本地的package/a..
-- node_modules
| -- packages/a - ../packages/a
-- package-lock.json
-- package.json
-- packages-- a| -- package.json上述的-- packages/a - ../packages/a指的就是从node_modules中a链接到本地npm包的软链3package.json环境相关属性常见的环境基本上分为浏览器browser和node环境两大类接下来我们来看看package.json中跟环境相关的配置属性。环境的定义可以简单理解如下browser环境比如存在一些只有在浏览器中才会存在的全局变量等比如windowDocument等node环境: npm包的源文件中存在只有在node环境中才会有的一些变量和内置包内置函数等。3.1 typejs的模块化规范包含了commonjs、CMD、UMD、AMD和ES module等最早先在node中支持的仅仅是commonjs字段但是从node13.2.0开始后node正式支持了ES module规范在package.json中可以通过type字段来声明npm包遵循的模块化规范。//package.json
{name: some package,type: module||commonjs
}需要注意的是不指定type的时候type的默认值是commonjs不过建议npm包都指定一下type当type字段指定值为module则采用ESModule规范当type字段指定时目录下的所有.js后缀结尾的文件都遵循type所指定的模块化规范除了type可以指定模块化规范外通过文件的后缀来指定文件所遵循的模块化规范以.mjs结尾的文件就是使用的ESModule规范以.cjs结尾的遵循的是commonjs规范3.2 main module browser除了type外package.json中还有main,module和browser 3个字段来定义npm包的入口文件。main : 定义了 npm 包的入口文件browser 环境和 node 环境均可使用module : 定义 npm 包的 ESM 规范的入口文件browser 环境和 node - 环境均可使用browser : 定义 npm 包在 browser 环境下的入口文件我们来看一下这3个字段的使用场景以及同时存在这3个字段时的优先级。我们假设有一个npm包为demo1,----- dist|-- index.browser.js|-- index.browser.mjs|-- index.js|-- index.mjs其package.json中同时指定了main,module和browser这3个字段main: dist/index.js, // main module: dist/index.mjs, // module// browser 可定义成和 main/module 字段一一对应的映射对象也可以直接定义为字符串browser: {./dist/index.js: ./dist/index.browser.js, // browsercjs./dist/index.mjs: ./dist/index.browser.mjs // browsermjs},// browser: ./dist/index.browser.js // browser默认构建和使用比如我们在项目中引用这个npm包import demo from demo通过构建工具构建上述代码后模块的加载循序为_browsermjs module browsercjs main_这个加载顺序是大部分构建工具默认的加载顺序比如webapck、esbuild等等。可以通过相应的配置修改这个加载顺序不过大部分场景我们还是会遵循默认的加载顺序。3.3 exports如果在package.json中定义了exports字段那么这个字段所定义的内容就是该npm包的真实和全部的导出优先级会高于main和file等字段。举例来说{name: pkg,exports: {.: ./main.mjs,./foo: ./foo.js}
}import { something } from pkg; // from pkg/main.mjsconst { something } require(pkg/foo); // require(pkg/foo.js)从上述的例子来看exports可以定义不同path的导出。如果存在exports后以前正常生效的file目录到处会失效比如require(pkg/package.json)因为在exports中没有指定就会报错。 exports还有一个最大的特点就是条件引用比如我们可以根据不同的引用方式或者模块化类型来指定npm包引用不同的入口文件。// package.json
{ name:pkg,main: ./main-require.cjs,exports: {import: ./main-module.js,require: ./main-require.cjs},type: module
}上述的例子中如果我们通过const p require(pkg)引用的就是./main-require.cjs。如果通过import p from pkg引用的就是./main-module.js最后需要注意的是 如果存在exports属性exports属性不仅优先级高于main同时也高于module和browser字段。4package.json依赖相关属性package.json中跟依赖相关的配置属性包含了dependencies、devDependencies、peerDependencies和peerDependenciesMeta等。dependencies是项目的依赖而devDependencies是开发所需要的模块所以我们可以在开发过程中需要的安装上去来提高我们的开发效率。这里需要注意的时在自己的项目中尽量的规范使用形如webpack、babel等是开发依赖而不是项目本身的依赖不要放在dependencies中。dependencies除了dependencies和devDependencies本文重点介绍的是peerDependencies和peerDependenciesMeta。3.1 peerDependenciespeerDependencies是package.json中的依赖项,可以解决核心库被下载多次以及统一核心库版本的问题。//package/pkg
----- node_modules|-- npm-a - 依赖了react,react-dom|-- npm-b - 依赖了react,react-dom|-- index.js比如上述的例子中如果子npm包a,b都以来了react和react-dom,此时如果我们在子npm包a,b的package.json中声明了PeerDependicies后相应的依赖就不会重新安装。需要注意的有两点对于子npm包a,在npm7中如果单独安装子npm a,其peerDependicies中的包会被安装下来。但是npm7之前是不会的。请规范和详细的指定PeerDependicies的配置笔者在看到有些react组件库不在PeerDependicies中指定react和react-dom或者将react和react-dom放到了dependicies中这两种不规范的指定都会存在一些问题。其二正确的指定PeerDependicies中npm包的版本react-focus-lock\2.8.1[1],peerDependicies指定的是react: ^16.8.0 || ^17.0.0 || ^18.0.0但实际上这个react-focus-lock并不支持18.x的react3.2 peerDependenciesMeta看到“Meta”就有元数据的意思这里的peerDependenciesMeta就是详细修饰了peerDependicies比如在react-redux这个npm包中的package.json中有这么一段peerDependencies: {react: ^16.8.3 || ^17 || ^18},peerDependenciesMeta: {react-dom: {optional: true},react-native: {optional: true}}这里指定了react-dom,react-native在peerDependenciesMeta中且为可选项因此如果项目中检测没有安装react-dom和react-native都不会报错。值得注意的是通过peerDependenciesMeta我们确实是取消了限制但是这里经常存在非A即B的场景比如上述例子中我们需要的是“react-dom”和react-native需要安装一个但是实际上通过上述的声明我们实现不了这种提示。5package.json三方属性package.json中也存在很多三方属性比如tsc中使用的types、构建工具中使用的sideEffects,git中使用的huskyeslint使用的eslintIgnore这些扩展的配置针对特定的开发工具是有意义的这里不一一举例。参考资料[1]mailto:react-focus-lock2.8.1: https://link.juejin.cn?targetmailto%3Areact-focus-lock%402.8.1················· 若川简介 ·················你好我是若川毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇在知乎、掘金收获超百万阅读。从2014年起每年都会写一篇年度总结已经坚持写了8年点击查看年度总结。同时最近组织了源码共读活动帮助4000前端人学会看源码。公众号愿景帮助5年内前端人走向前列。扫码加我微信 ruochuan02、拉你进源码共读群今日话题目前建有江西|湖南|湖北 籍 前端群想进群的可以加我微信 ruochuan12 进群。分享、收藏、点赞、在看我的文章就是对我最大的支持~