什么是package
package
指拥有 package.json
的一个文件夹(或压缩包),而 package
的属性就是 package.json
文件的内容,比如:
name
:这个包叫什么名字,唯一version
:这个包的版本号是多少main
:这个包默认引入的是哪个文件homepage
:这个包的官网或者文档
semver
semver
,语义化版本,它由[major,minor,patch]
三部分组成,其中
major
:包中发生Api级别的变化时,递增major版本号minor
:新增一个向后兼容的功能时,递增minor版本号patch
:修复一个向后兼容的bug时,递增patch版本号
除此之外,一些大型包的管理中,如果没有正式发布,会选择使用prerelease
版本号,例如1.0.0-alpha
。在比较小的包就没必要使用。
semver
与语言无关,不仅在 JavaScript 中使用 semver,在其它一些语言中也可以使用 semver 该语义化版本命名版本号。
我们接下来拿vue
举一个例子
-
Vue 2 到 Vue 3 的迁移是一个 major 版本更新的例子,涉及了不兼容的重大变化,比如:
- Composition API 替代 Options API: 从 Vue 2 的 Options API 到 Vue 3 的 Composition API,组件逻辑写法有较大改变。
- 基于 Proxy 的响应式系统: Vue 3 使用 Proxy 取代了 Vue 2 的 Object.defineProperty,影响了响应式数据的更新和追踪。
- Fragment 语法: Vue 3 引入了 Fragment 语法,不需要像 Vue 2 一样在模板中使用额外的包装元素。
-
如果 Vue Router 新增了一个向后兼容的功能,会递增 minor 版本号。假设在
3.0.0
版本中没有的导航守卫的选项被添加到3.1.0
版本,这个变化不会影响到已有的导航守卫。 -
当 Vue Router 修复一个向后兼容的 bug 时,会递增 patch 版本号。例如,假设
3.0.0
版本中的一个已知 bug 被修复,就会发布3.0.1
版本。
版本号范围
当我们手动安装一个包,它写在 package.json 中的是一个版本号范围。
js
{
dependencies: {
lodash: '~1.8.1'
}
}
版本号一般有~ ^
两种
对于~1.2.3
来说,它的版本号范围是>=1.2.3 <1.3.0
对于^1.2.3
来说,它的版本号范围是>=1.2.3 <2.0.0
我们在写项目时可以使用 yarn.lock/package-lock.json
锁定版本号。
依赖
依赖分为dependency
和devdependency
两种
它们两者之间的区别就是一个是项目运行时所需要的依赖,一个是开发时的依赖是不会打包进最终产物的。
除此之外,它们在包开发和项目开发时也有差别。
- 在开发包时,
devdependency
和dependency
需要有严格的区分,因为在npm i xxx
时,只会下载xxx包package.json目录下的dependency
,如是略有差错,项目就会出错, - 在开发项目时,这两者就不必要有很严格区分。不管是使用
webapck
还是vite
打包项目时,这些打包工具都会对项目依赖进行分析,用到的打包,不用的剔除。不过作为一种规范,能遵守还是得遵守。
URI as dependency
{
"dependencies": {
"npm": "git+ssh://git@github.com:npm/cli.git",
"foo": "http://q.shanyue.tech/foo.tar.gz",
"bar": "file:../bar"
}
}
这种写法常用于一个项目依赖另一个项目,但又不想发包,我们就可以直接用它仓库url作为依赖。
依赖别名
一个项目需要用到一个包的两个版本,此时我们就需要使用依赖别名来区分
js
$ npm install <alias>@npm:<name>
$ npm install vue2@npm:vue@2
$ npm install vue3@npm:vue@3
package.json
:
{
"dependencies": {
"vue2": "npm:vue@2",
"vue3": "npm:vue@3"
}
}
sideeffects
sideEffects
用于指示npm包是否具有副作用。
副作用指的是模块在导入时会产生除了导出值之外的其他影响,比如修改全局变量、执行一些代码等。在现代的 JavaScript 模块系统中,为了优化打包和代码分割,打包工具(比如Webpack)会尝试去除那些没有副作用的模块,以减小打包后的代码体积。
在package.json
中,我们可以通过以下方式配置sideEffects
json
{
"name": "redux",
"version": "5.0.0-beta.0",
"sideEffects": false
}
false
: 表示模块没有副作用,可以被安全地删除。这通常用于纯粹的导出模块,例如只包含函数、类、对象等,没有执行任何其他操作的模块。true
: 表示模块具有副作用,不会被删除。这是默认值,如果你不在package.json
中显式设置sideEffects
,那么模块会被认为具有副作用。- 字符串数组:可以列出模块中具有副作用的文件的路径。这些路径会被用于指定哪些模块具有副作用,从而防止它们被删除。
使用场景举例:
json
{
"name": "my-react-app",
"dependencies": {
"react": "^16.0.0",
"react-dom": "^16.0.0",
"lodash": "^4.0.0"
},
"sideEffects": [
"node_modules/lodash/*.js"
]
}
在这个例子中,我们使用了React和React DOM作为依赖项,并且还使用了Lodash库。但是,我们可能只使用了Lodash的部分功能,其他部分具有副作用。通过设置 sideEffects
字段,我们告诉打包工具只保留Lodash库中我们使用的部分,并且删除没有副作用的部分。这可以显著减小打包后的代码体积,提高应用程序加载速度。
一句话概括它的作用:打包器webpack、vite等
通过这个字段进行Tree Shaking
优化,它会安全地删除未使用的模块,减小最终打包体积。