文章目录
1. library的打包
前面讲解的都是对自己的业务代码来打包,这里阐述一下如何利用webpack来打包自己的库代码,这里我们以一个简单的函数库为例
编写基础代码
首先我们新建一个library文件夹,进入其中然后初始化:
npm init -y
生成package.json文件,接着新增一个src文件夹,创建我们的函数库文件math.js和string.js,里面写工具函数:
// math.js
export function add(a,b){
return a+b;
}
// string.js
export funtion join(a,b){
return a + '' + b;
}
最后写一个index.js文件作为入口文件:
import * as math from './math'
import * as string from './string'
//暴露出去
export default {math,string}
这时候本地运行的话浏览器肯定没办法识别,需要借助webpack来进行打包
webpack的安装和配置
这里我们再复习一下过程,首先当前工程下安装webpack:
npm install webpack webpack-cli --save
接着创建webpack的配置文件webpack.config.js:
const path = require('path')
module.exports = {
mode:'production',
entry:'./src/index',
output:{
path:path.resolve(__dirname,'dist'),
filename:'library.js'
}
}
同时package.json里面写个脚本:
script:{
build: webpack
}
然后执行npm run build,不出意外会在dist目录下面生成library.js文件
其实这个library.js文件就是希望给别人使用的库文件
别人如何引入你的库文件
其他用户可能有很多方法来引入你的JS:
import library from 'library'
//或者
const library = require('library')
//或者amd
require(['library'],function(){
})
// script标签
<script src='library.js'></script>
//library.math来使用
这时候我们需要修改一下webpack的配置文件:
module.exports = {
...
output:{
path:...,
filename:...,
library:'library',
libraryTarget:'umd'
}
}
libraryTarget:主要用于配置库输出的规范,当值为umd是universal 配置,其他用户可以通过除了script标签之外方式来使用。
library:可以声明一个变量,一般配合libraryTarget的value来决定这个变量挂载的位置
这时候你可以重新打包然后本地测试一下通过script标签来引用你的JS文件:
// index.html
...
<script src='./library.js'></script>
...
这里一般来说填写umd就可以了,保证大部分情况下都可以正常引入
externals参数
有的时候会存在库中复用其他第三方库的情况,例如我们的string.js引用了lodash的工具:
import _ from 'lodash';
export function join(a,b){
return _.join([a,b],' ')
}
但是这里针对第三方用户来说如果按照上述打包方式,他们可能会引入lodash的代码,如果之前已经install lodash,那么最终产物很可能包含两份lodash代码
这里就可以配置externals来解决:
externals:["lodash"]
打包过程中如果遇到了lodash这个库就忽略这个库,不打包到node_modules。
用户使用的时候会需要在业务代码里面引入lodash,这里库就可以external来使用用户引入的lodash,解决了之前的问题。
库文件上传
接着如果其他用户想用你的库,你还需要将其上传到npm上,可以简单修改一下package.json里面的入口和项目名称(防止冲突):
{
"name":"library-joern-lee",
"version":"0.0.1",
...
"main":"./dist/library.js",
...
}
然后npm adduser进行登录,再执行npm publish命令就可以发布你的库文件了,别人npm install就可以了~
2. PWA打包
PWA全称是渐进式网页应用,一种相对还蛮新的概念,感兴趣的可以自己了解一下,这里只说说webpack相关的打包问题
模拟服务器引入PWA
这里我们本地模拟一下服务器,来看看没有PWA情况下的网页响应:
首先我们按照一个http-server来模拟远程服务器运行我们的打包文件:
// package.json
"scripts":{
"start":"http-server dist"
...
}
然后可以看到再本地的8080起了一个服务,可以正常访问,但是当我们关闭服务器之后再刷新页面,就访问失败
就是传统的网页,而PWA这种技术可以实现一种效果:第一次访问成功之后,可以在本地有一份网页缓存,即便服务器挂掉,还是能看到页面,想实现PWA的效果,可以基于facebook的webpack插件来快速实现这种效果。
PWA插件
npm install workbox-webpack-plugin --save-dev
接着修改配置文件,引入该插件:
...
const WorkBoxPlugin = require('workbox-webpack-plugin');
...
module.exports = {
...
plugins:[
...,
new WorkboxPlugin.gennerateSw({
clientsClaim:true,
skipWaiting:true
})
]
}
然后重新打包,会发现dist目录下多了一个service-worker.js和precache-manifest的文件,现在我们的页面有了一个缓存了(service worker是PWA底层的一种实现技术)
应用service-worker实现PWA
要实现PWA还需要写一些业务代码:
//index.js
if('serviceWorker' in navigator) {
window.addEventListener('load',()=>{
navigator.serviceWorker.register('/service-worker.js')
.then(registration =>{
//注册成功,可以做一些事情
console.log('registed')
}).catch(error =>{
console.log('error')
})
})
}
简单来说就是当浏览器支持service-worker情况下,注册一下然后做自己的逻辑
然后我们重新打包运行,可以看到控制台提示你已经缓存了页面,这时候我们关闭服务器,刷新页面,依然可以正常看到原有界面
当然上述只是基础中的基础,SW提供了很多函数和功能,而且Webpack插件也有很多配置项,这一块感兴趣还是需要深入相关知识点
3. Typescript(TS)打包
TS是微软产品,规范了一套JS语法,是JS超集,静态报错提示,有效提升可维护性,越来越多公司开始采用TS,但是使用TS的话,打包配置也会有差异。
编写demo工程
老规矩,初始化项目并安装webpack
接着我们写一个TS源代码文件,注意以ts作为文件后缀:
class Greeter{
greeting:string;
constructior(message:string){
this.greeting = message;
}
greet(){
return "Hello" + this.greeting
}
}
let greeter = new Greeter("joern");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function(){
alert(greeter.greet());
}
document.body.appendChild(button)
用到了TS关于类型定义,class,构造函数等等语法。
这里直接运行肯定不行,需要借助webpack
webpack配置
这时候就需要相应的loader登场了来识别ts文件类型进行处理。
const path = require('path')
module.exports = {
mode:'production',
entry:'./src/index.ts',
module:{
rules:[{
test:/\.tsx?$/,
use:'ts-loader' //官方TSloader
exclude:/node_modules/ //不处理node_modules下面的
}]
}
output:{
filename:'bundle.js'
path:path.resolve(__dirname,'dist')
}
}
然后安装ts-loader,记得还要安装typescript,不然根本没办法写TS:
npm install ts-loader typescript --save-dev
然后重新打包,这里会错误提示缺少一个tsconfig.json文件,这是因为项目根目录需要创建一个tsconfig.json配置文件用来配置TS。
tsconfig.json配置文件
只写一些简单参数,具体深入配置参考官网:
{
"compilerOptions":{
"outDir":"./dist", //输出目的地
"module":"es6", //使用es6方式引入模块
"target":"es5", //打包成es5语法
"allowJs":"true" // 允许引入JS文件
}
}
然后重新打包就可以啦
ts中引入库文件时注意事项
这里再多说一些关于ts中引入一些库的注意事项。
通过常规方法引入一些库,例如lodash,即便lodash传入的参数类型错误也不会报错。这是因为lodash这里引入的只是JS文件,没有引入lodash的类型文件:
npm install @types/lodash --save-dev
然后具体库函数就会报类型错误了。
总之我们引入第三方库时,不要忘了安装对应的类型文件@types。
那我们怎么知道哪些需要安装类型文件呢,可以打开github,找到DefinitelyTypes项目里面的TypeSearch,借助该工具搜索就可以看到哪些库有@ttypes类型文件了,如果有就安装一下吧~