UI 框架的集成
这一章中我们把之前完成的代码进行优化、整合和包装,达到可以在实战项目中直接使用的状态。在这一章的内容里,会涉及到一些基于 nodejs 的工具,并且会使用 shell 脚本来完成一些辅助的工作。
我们这一章主要包含两部分内容。第一部分是把我们之前零散的文件打包成一个最终压缩好的文件,提供给传统的项目使用。第二部分是再把压缩好的目标文件依照 npm 包的规则进行修改,并发布到 npm 源上,提供给一些基于 npm 的项目使用。下面来简单说下这两部分内容里都要做哪些事。
一、文件方式的集成
在以文件方式集成中,我们会处理如下几个问题:
- 源文件中都是使用 @import 做的文件引入,我们需要借助工具对 @import 做解析,把零散的文件集合到一个 CSS 文件中。
- 之前在书写样式的时候,没有写兼容的语句,这里我们要借助工具来解决兼容性问题。
- 最后要把文件做最小化的压缩,生成 .min.css 的文件提供给别的项目引用。
- 使用 shell 脚本完成整个集成的过程,减少命令的输入。
二、制作并发布 npm 包
在使用 npm 方式集成的时候,我们会利用上一步打包生成的样式文件。但在前面生成文件的基础上,我们会更改这个项目对字体图标库的依赖方式,以符合 npm 的规范。这一节我们在适配完 npm 包,还会把做好的 npm 包发布到 npm 官网上。
使用文件形式直接集成
我们这一章来做 UI 样式库的集成,在上一章的开篇中也提到了,现在这个样式库还存在以下三个问题:
- 使用 @import 引用了太多的文件,会拖慢加载速度,不可能直接用在生产环境。
- 没有处理兼容性的问题,要添加兼容性写法。
- 文件没有压缩,体积会比较大,同样会影响加载速度。
我们就是要解决这几个比较关键的问题。最后,我们会得到一个解决掉这些问题后的最终文件,就可以直接在生产环境使用了。最终会生成下面这两个目标文件:
- /dist/my-ui.min.css
- /dist/my-ui.css
其中 /dist/my-ui.min.css 就是我们可以在生产环境使用的最终文件。此外还生成了一个非压缩的 tuitui-ui.css,这个文件和压缩后的文件内容是一样的,只不过没有进行压缩。生成这个文件是为了可以看到带有格式的最终文件,如果出现问题可以快速定位出问题的地方。
环境的搭建
在做打包的时候,我们需要使用一些工具来辅助,我们先把这些工具介绍一下。
一、Node.js + npm + npx
首先是 Node.js + npm + npx 这个套装,下来介绍这三个都是做什么的:
@ Tips:
Node.js 是运行在服务端的 JS 语言,可以用来处理前端的文件,它是我们这一节要用到的工具的环境基础。
npm (Node.js Package Manager) ,是 Node.js 的包管理工具,主要用来管理 Node.js 项目的依赖包,包括对包的安装、查看和卸载等。
npx,这个工具是 Node.js 插件的执行工具,它可以执行 npm 包中包含的命令。
然后我们安装 Node.js,Windows 和 Mac 用户都可以在Node.js官网 下载对应的安装包(Widnows 下载 .msi 格式的文件,Mac 下载 .pkg 格式的文件),然后直接安装就可以了。我这里用的是 8.16.0 的版本,里面会包含 Node.js、npm 和 npx 三个工具。安装好以后,在命令行里执行下面命令来查看 Node.js、npm 和 npx 的版本:
如果发现 npx 没有的话,可以执行下面命令手动安装:
- npm i npx@6.4.1 -g
最后一步,就是要把我们之前的项目,使用 npm 初始化一下,这样才可以使用 npm 来安装需要的插件。在项目目录里执行下面的命令:
- npm init
随后输入项目相关的信息,包括名称、版本、关键词等,这里什么都不输入,直接回车也不会影响使用,以后也可以再改。
完成后就会在项目根目录中,生成一个 package.json 文件:
{
"name": "my-ui",
"version": "1.0.0",
"description": "my-ui",
"main": "-",
"scripts": {
"test": "-"
},
"repository": {
"type": "git",
"url": "git@gitee.com:mytech/my-ui.git"
},
"keywords": [
"my-ui",
"mytech",
"ui"
],
"author": "mytech",
"license": "ISC"
}
这个文件就是 npm 的配置文件了,这样,有关 Node.js 的工作就完成了。
二、postcss
这里要介绍的第二个内容是,基于 Node.js 的postcss工具。这是一个 CSS 处理工具,在使用的时候还需要搭配其他的插件来配合。我们先使用 npm 把这个插件安装上,这里我们直接使用命令行工具来安装这个插件,所以安装的插件名称应该是“postcss-cli”。
- npm i postcss-cli@6.1.3 -D
这条命令里 -D 的含义是把这个包的版本信息记录在 package.json 里的 devDependencies 字段里,表示这是在开发过程会使用到的插件。
这样这个插件就装好了,我们可以用下面的命令来测试一下:
npx postcss src/my-ui.css -o dist/my-ui.css
这条命令的含义就是使用 npx 调用了 postcss-cli 提供的 postcss 命令,后面跟着的就是一些参数。这条命令实际的格式是:
npx postcss 要处理的 CSS 文件位置 -o 生成目标文件的位置
执行完这一条命令后,就会在根目录下生成一个 dist 目录,里面就是刚生成的my.css。但是命令行里会提醒你,没有使用任何插件,最后生成的文件基本没什么处理,只是在主文件的最后加了个 sourceMapping,我们后面再加上其他插件来处理。走到这里没有问题的话,就说明我们的环境就配置好了。
对 @import 的处理
接下来处理 @import 的问题,这里要使用到“postcss-import”这个插件。这个插件可以把 @import 方式引入的本地路径转变成这个路径里的 CSS 语句。经过这样处理以后,所有的样式文件就会被集中到目标文件里,@import 只剩下一个远程的路径,项目本地的 @import 就没有了。
我们先来安装一下这个插件:
npm i postcss-import@12.0.1 -D
安装好以后,我们就可以在刚才的打包命令里添加这个插件来完成对@import的处理:
npx postcss src/my-ui.css -o dist/my-ui.css -u postcss-import --no-map
这里我们在之前的命令后面又加了些东西,“-u postcss-import”是表示在使用 postcss 处理 CSS 文件时要使用“postcss-import”插件。最后多的“–no-map”是为了去掉生成文件最后的sourceMapping信息。经过这样处理,会发现目标文件里的内容就变多了,各个文件的内容都被集成到这一个文件里了:
@ Tips:
这里要注意两个问题:
1、文件中引入字体图标库用的远程 @import 并不会被替换,但会被提到文件的最前面。
2、我们的项目里没有涉及图片,如果需要处理图片的项目可以使用“postcss-url”来处理图片的路径问题。
对兼容性的处理
接下来要处理兼容性问题。目前来看,大部分 CSS3 的样式已经可以在新的浏览器上运行了,但是,有些属性或者属性值是要添加浏览器前缀后才可以用,所以我们还是要对代码进行兼容处理。在处理移动端样式的问题时,我们不再手动添加浏览器前缀,这里要介绍一个叫做“Autoprefixer”的插件。这个插件会分析代码,并根据Can I use这个网站提供的兼容性数据来自动添加兼容写法。下来我们先安装一下这个插件:
npm i autoprefixer@9.6.1 -D
安装好以后就可以直接在命令中使用这个插件了:
npx postcss src/my-ui.css -o dist/my-ui.css -u postcss-import autoprefixer --no-map
这条命令执行后,就可以去文件中找到一些样式被添加上了兼容写法,以我们之前开发的图标,上下振动的样式为例。原有代码:
处理后的代码:
经过前后对比,就可以发现,原有代码中的 animation 和 @keyframes 都被添加了兼容写法,但是 transform 并没有添加兼容写法。这是因为默认情况下, autoprefixer 会给没有废弃的且占有率 > 0.5% 或者是最新发布的两个版本以内的浏览器提供兼容支持,但是这种配置不一定安全,所以我们也可以自己去调节这个兼容范围的配置。autoprefixer 的兼容性配置方式使用的是browserslist工具提供的规则,所以我们按着 browserslist 的规则来配置需要的规则就可以了,这个工具需要在项目的根目录上建立“.browserslistrc”这个文件:
我们使用的是这样的配置,指定了对覆盖率大于 0.5% 或者是最新 2 个版本内的浏览器提供支持,并且可以不支持旧版本的 IE 和 IE_Mob。和默认配置相比,是去掉了not dead这个选项,表示对已经废弃的浏览器版本也提供前面规则的支持,这样会更安全一点。经过这样的配置再重新执行前面的命令,就会发现像 transform 这种属性也会被添加兼容写法:
我们使用的这个配置方式比较笼统,而 browserslist 可以支持区分浏览器的设置。到这里我们对兼容性的处理也完成了。
压缩CSS文件
最后一个要处理的问题就是压缩了,这里要使用的插件是“cssnano”。这个工具会把CSS文件里的注释和空格都去掉,经过处理后就可以生成我们最终需要的压缩文件了。我们还是先来安装这个插件:
npm i cssnano@4.1.10 -D
这个插件也可以直接按着默认配置来使用,可以按下面的命令进行执行:
npx postcss src/my-ui.css -o dist/my-ui.min.css -u postcss-import autoprefixer cssnano --no-map
这里我们把输出的文件名改成了 dist/my-ui.min.css,这表示是压缩后的文件。执行完这条命令以后,原来文件中的注释和空格就都被去掉了,最后会生成一个新的 /dist/my-ui.min.css
这样我们把文件压缩的问题也解决了,最后生成的这个文件我们就可以直接在别的项目使用了。
shell脚本的编写
最后一步,我们来写一个 Shell 脚本来记录下前面的命令,免得每次打包都要输入那么一大串的命令。Shell 脚本通常是在Linux 或者 Mac 系统上才能使用的一种命令式语言,但 Windows 上使用 gitbash 这类工具的话也能支持一部分 Shell 命令。我们先在根目录下建一个名为“shell”的目录,然后在里面放一个“build.sh”的文件:
# 清空dist目录中的旧文件
echo '正在清除原有dist文件...'
rm -rf dist/*.css
# 打包出不压缩的CSS文件my-ui.css
echo '正在生成tuitui-ui.css文件...'
npx postcss src/my-ui.css -o dist/my-ui.css -u postcss-import autoprefixer --no-map
# 打包出被压缩的CSS文件my-ui.min.css
echo '正在生成my-ui.min.css文件...'
npx postcss src/my-ui.css -o dist/my-ui.min.css -u postcss-import autoprefixer cssnano --no-map
这个脚本很简单,就是顺序执行几条命令:
- 首先是清空原有的 dist 目录,来避免一些不必要的错误。
- 然后执行生成 /dist/my-ui.css 文件的命令,就是刚才在解决兼容性问题时用的那条命令。
- 最后执行生成 /dist/my-ui.min.css 这个压缩文件的命令,也就是上一步我们用过的那条。
制作完这个脚本以后,再想打包项目,就可以直接在项目里调用这个脚本了。可以在项目根目录执行:
./shell/build.sh
使用 npm 形式集成
我们这一章用 npm 的方式来集成代码。我们会介绍 npm 包的结构、npm 包的制作和发布过程。
npm包的介绍
npm 是 JS 的包管理工具,我们可以用它来下载已有的代码,可以很快的引用别人发布过的代码。前面我们已经使用 npm 安装了几个工具,那几个工具其实就是几个 npm 包。安装好的 npm 包会被放在项目里的 node_modules 里,我们找一个包来看下它是什么样的结构,以上一节用的 postcss-cli 为例:
这个包里的内容并不多,这里面最重要的就是“package.json”这个文件,有了这个文件,就可以说这是一个 npm 包的结构了,而另外的文件就是插件功能逻辑的源码和一些说明文件。
当我们引用这个插件的时候,Node.js 就会读取 package.json 里的内容,根据 main 字段指定的路径去引用对应的文件。postcss-cli 这个插件的入口文件就是“index.js”,在“index.js”里又会引用lib目录里的代码。
这个插件还需要对外提供可执行文件,就是我们使用 npx 工具调用的 postcss 命令,所以会在 bin 目录里放上可执行文件,然后再在配置文件里的“bin”字段配置上可执行文件的目录位置。这个目录里其他几个文件,就是一些版权声明或者插件介绍这些说明性质的文件了,对代码的运行没有实际作用。
package.json 文件是一个 JSON 格式的配置文件,所有插件相关的信息都会记录在这个文件里。下来我们来介绍下package.json 里几个比较重要的字段。
- name:这个字段指定 npm 包的名称,我们发布 npm包以后,包的名称就是这个字段指定的,和目录名称没什么关系。
- version:这是 npm 插件的版本号,每次发布的时候不能使用原来的版本。
- description:npm 包的描述信息,用比较简短的语言描述这个插件是做什么的。
- keywords:npm 包的一些关键词,用户可能会根据这些关键词模糊搜索到你的插件,如果希望你的 npm 包更容易被找到,可以好好设计一下这个关键词。
- main:这是npm包的主文件,通常是一个 JS 文件,但这个字段也可以是 CSS 文件。
- license:指定 npm 包的开源模式,是只允许调用代码,还是可以随意改动。
- dependencies:这是一个很重要的字段,在 npm 包中,你可以使用其他的插件,这个字段就是指定你这个包都需要哪些依赖的。只要和上一节中那样把需要的插件名称和版本填写到这个字段中,就可以直接引用了。
- devDependencies:这个字段和上面一个很类似,它俩的区别就是所安装插件的作用不同,dependencies 记录的通常是会被打包到最终代码里的 npm 包,而 devDependencies 字段记录的是开发过程需要用到的 npm 包。
npm包的制作
下来我们开始制作 npm 包,这个过程分三步来实现,分别是项目初始化、依赖的配置和添加文件说明。
一、项目初始化
我们这里为了减少 npm 包里的文件,不打算在原有的项目上直接进行发布,会重新建立一个新的项目。我们先建一个名为“my-ui-npm”的目录,然后和上一节一样,在目录下执行下面的命令对目录进行 npm 的初始化:
npm init
这样就生成好了 package.json 文件:
{
"name": "my-ui",
"version": "0.1.1",
"description": "my-ui",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"my-ui",
"mytech",
"ui",
"mobile"
],
"author": "mytech",
"license": "ISC"
}
现在,这就是一个 npm 项目了,这里我们把版本先定到“0.1.1”,等使用一段时间稳定后再把版本从“1.0.0”开始计算。接下来我们在 my-ui-npm 目录下创建一个名为“css”的目录,然后把之前项目里生成的最终文件 my-ui.min.css 移到新建好的 css 目录里。这样项目初始化的工作就完成了。
二、依赖的配置
这一步我们来配置依赖,我们之前打包好的样式是使用网络地址来加载依赖文件 font-awesome 的。但在 npm 中,要遵循 npm 的设计规则,在插件里再引用网络地址就不太合适了,所以我们这一步就是要更改项目依赖的引入方式。
这里我们使用 npm 引入依赖的方式,首先要在新的这个项目中安装 font-awesome 依赖,命令如下;
npm i font-awesome@4.7.0 -S
-S 参数就是在 dependencies 里记录所安装插件的信息,这样项目的依赖就安装好了,package.json 里多了下面这段内容:
"dependencies": {
"font-awesome": "^4.7.0"
}
有了这个依赖,原来打包好代码里的网络地址就可以去掉了.
最后一步,我们再在根目录下添加一个index.js文件,把需要的两个css文件都引入进去。
@ TIps:
这里有两个地方要注意下:
1、npm工具只能通过js来引入包,不能直接用css引用其他的插件。
2、在index.js里引入css文件,这种引用方式只有在像webpack这种可以把CSS当做JS模块来处理的工具里才可以使用。如果是其他情况就要手动的用路径去引用CSS文件。
这样我们这个项目的依赖配置就完成了。
三、添加说明文件
最后,在这个项目里添加一个简单的说明文件,在根目录下建立一个“README.md”文件:
# my-ui样式库
## 说明
本插件依赖font-awesome@4.7.0,安装本插件的同时也会安装font-awesome。在使用本UI样式库的时候可以直接引用对应的CSS文件:
import 'font-awesome/css/font-awesome.min.css';
import 'my-ui/css/my-ui.min.css';
同时,本插件已经使用js文件打包了两个css文件,在支持CSS模块的项目里也可以像下面这样直接引用插件:
import 'my-ui';
这样我们的 npm 包就建好了,下一步我们要把它发布到npm上。
npm包的发布
下来我们做 npm 的发布,这一步其实比较简单。
一、注册npm帐号
如果想在npm上发布新的代码包,必须注册称为 npm 的用户,官方地址是https://www.npmjs.com/。进入后点Join按钮就可以进入用户注册页面了。在注册页面填上相关信息,然后创建一个新的用户就行了。
二、发布前的检查
如果要把代码包发布到官方的 npm 源上,要确保我们当前使用 npm 源也是官方的。像淘宝源这些非官方源只支持npm包的下载,但会明确说明不能支持 npm 包的发布。
下来我们检查一下本机用的到底是哪个源,在命令行中输入下面的命令:
npm config get registry
如果要改回到官方的源地址,可以直接用命令来切换:
npm config set registry https://registry.npmjs.org
这样 npm 源就切换成功了。接下来还要检查下我们要发布的npm包的名称是不是有重复的,可以在npm官网上搜索一下你要发布的包名,如果像下面这样找不到重名的包,就可以进入发布工作了。
三、npm包的发布
最激动人心的一步来了,我们要把这个源发布到 npm 上了。首先要在项目目录里执行下面命令来初始化 npm 用户信息:
npm adduser
执行完命令后输入你注册时使用的用户名和密码,另外还要输入一个用于接收消息的电子邮箱地址,都完成后就完成了登录:
这里要注意,只有在第一次发布的时候才需要使用“npm adduser”命令,如果以后再登录,直接使用下面的命令就可以了:
npm login
这个命令一执行成功,你的代码就发布到 npm 上了,所以这个操作要稍微慎重一点,确认好代码没有问题了再去执行。发布完成以后,会有一个很简单的提示,这看起来根本不像刚做了一个很手抖的操作。
这样我们的包就发布完了,现在可以直接在其他项目中直接使用 npm下载我们的 UI 样式库了:
如果发现我们发布的版本有问题的话,在 24 小时以内还是可以对发布的版本进行删除。这是因为担心你发布的包被别的项目引用后,如果你删掉会导致使用你 npm 包的项目全都废掉,所以会有个时间限制。这里建议如果不是很严重的问题,最好使用“npm deprecate”命令来标记这个版本是废弃的,而不是去强行删除掉。
到这里 npm 包的发布工作就全部完成了。