使用webpack+ts做一个贪吃蛇游戏(二)---webpack编译的兼容性处理(babel和postcss)

一、babel
babel可以将高版本的js代码转换为低版本的js代码,从而达到兼容旧浏览器(比如IE)的目的。一些ES6的类和方法,比如Promisebabe会通过低版本js可以运行的方法重新实现,然后在代码中使用。

  1. 安装babel
npm i -D @babel/core @/babel/preset-env babel-loader core-js

其中,@babel/corebabel的核心工具库。
@babel/preset-envbabel的预置环境,这个包里预置了很多环境,比如谷歌某版本、IE某版本、火狐某版本等,设置了什么版本,babel编译的时候就相应的编译成什么样的js
babel-loaderbabelwebpack中的加载器,用来将babelwebpack关联起来。
core-js是模拟js运行环境的代码,提供了es5、es6polyfills,包括promises、symbols、collections、iterators、typed arrays、ECMAScript 7+ proposals、setImmediate等等。core-js里面东西很多,在实际配置的时候,会按需选择一部分使用。

2.如何使用

// webpack.config.js
// 首先在rules里加上babel对ts文件的处理
{
                // test指定的是规则生效的文件
                test: /\.ts$/,
                // 要使用的loader
                use: [
                    // 配置babel
                    {
                        loader: 'babel-loader',
                        options: {
                            // 设置预置环境
                            presets: [
                                [
                                    // 指定环境的插件
                                    "@babel/preset-env",
                                    // 配置信息
                                    {
                                        // 要兼容的浏览器版本
                                        targets: {
                                            "chrome": "58",
                                            "ie": "11"
                                        },
                                        // 指定corejs的版本
                                        "corejs": "3",
                                        // 使用corejs的方式 usage表示按需加载
                                        "useBuiltIns": "usage"
                                    }
                                ]
                            ]
                        }
                    },
                    'ts-loader'
                ],
                // 要排除的文件
                exclude: /node_modules/
                // 这块配置的意思是,使用ts-loader处理所有以.ts结尾的文件,但排除掉node_modules文件夹
            }

我们修改了对ts文件的处理规则,之前只用到ts-loader,这次加上了babel-loader,当use属性中有多个loader的时候,可以通过数组的方式传入,loader如果没有特殊配置,写入名字即可,比如上面的ts-loader。如果有更详细的配置,可以传入一个对象,比如上面的babel-loader

需要注意的是:use中配置的loader是按照从后往前的顺序执行的,在上面配置中,首先通过ts-loaderts转为jsjs版本由tsconfig.json指定),然后通过babeljs转换为可兼容的js代码。

  1. 测试
// index.ts
const fn = (a:number, b:number) => a + b
fn(123, 456)

npm run build编译后,打开bundle.js

编译后的文件

可以看到,const被转成了var,箭头函数被转成了普通函数,通过babel,将ts转换的es6版本的js转成了ie可以兼容的es5的js代码。

在引入es6的Promise试试

// index.ts
const fn = (a:number, b:number) => a + b
fn(123, 456)
console.log(Promise)

编译后的文件大了很多,里面自己实现了promise

  1. bug
    到这里,我们得到的bundle.js按理说应该可以支持到IE浏览器了,但实际却发现报错了
    执行npm run start启动项目,在IE浏览器中打开,打开控制台,发现报错了。
    IE浏览器报错

    定位到错误的位置看看
    报错位置

    我们发现webpack打包的js,包裹在一个立即执行函数中,而这个函数里面,是一个箭头函数。IE不支持箭头函数,所以在最开始就报错了。
    这里有点疑问,我们不是用babeljs给转成旧版本js了吗,上面的例子中,箭头函数也被转成普通函数了,这里为什么会有一个箭头函数呢?

实际上,这里的箭头函数,是webpack的代码,而babel处理的是我们自己写的代码,所以它处理不到这块。可以看出webpack并不喜欢IE,默认不想支持它。所以应该怎么解决呢?

webpack配置的output对象中,增加一个配置,告诉webpack不要使用箭头函数以及const(不设置这个,在IE10浏览器中会因为const而报错)。

output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
        // 告诉webpack不使用箭头函数和const
        environment: {
            arrowFunction: false,
            const: false
        }
    }

在启动下用IE打开,发现没有报错了。
以上,关于babel的配置就告一段落了。
二、postcss

  1. 安装
npm i -D less less-loader css-loader style-loader

less-loaderless的加载器。
css-loader是用来进行css的模块化处理的。如果在JS中导入了css,那么就需要使用css-loader来识别这个模块,通过特定的语法规则进行转换内容最后导出,css-loader会处理import / require()以及 @import / url引入的内容。
style-loader是处理css的最终引用的,它在前面的包整理好引用关系后,在编译好的html中,通过js创建style标签,里面包含了css样式。

除了安装这些,还要安装postcss,postcss之于css,就像babel之于js,它可以将css转换为更具兼容性的写法。

npm i -D postcss postcss-loader postcss-preset-env

整体捋一下这些包的使用顺序:

  • less文件写样式
  • 编译的时候webpack首先使用less-loader加载less文件,并将less代码转换成css代码
  • 使用postcss-loader,根据配置将css代码转成更具兼容性的css代码
  • css-loader处理引用关系,知道应该在什么地方引入哪些css代码
  • style-loader通过js创建style标签,根据前面的引用关系,在合适的地方加入css代码
  1. 如何使用
// webpack.config.js 在module --> rules中指定less文件的加载规则
// 设置less文件的处理
            {
                test: /\.less$/,
                use: [
                    "style-loader",
                    "css-loader",
                    // 引入postcss
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    [
                                        "postcss-preset-env",
                                        {
                                            browsers: 'last 2 versions'
                                        }
                                    ]
                                ]
                            }
                        }
                    },
                    "less-loader"
                ]
            }

配置方法和babel类似,plugins中指定了postcss的预置环境,以及兼容性要求为支持每种浏览器的最新的两个版本。

  1. 测试
    src中创建styles/index.less文件
body {
  background: red;
  display: flex;
}

index.ts中引用这个css
import './styles/index.less'
编译后打开bundle.js,搜索flex

编译后的bundle.js

可以看到display:flex;加上了前缀,说明postcss的配置生效了。

经过两节时间,webpack的配置已经告一段落,后面章节将逐步实现贪吃蛇的小游戏。

你可能感兴趣的:(使用webpack+ts做一个贪吃蛇游戏(二)---webpack编译的兼容性处理(babel和postcss))