Webpack的配置案例-库、PWA、TS打包配置

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类型文件了,如果有就安装一下吧~

猜你喜欢

转载自blog.csdn.net/sdsh1880gm/article/details/109131052
今日推荐