项目场景:webpack4 + babel7配置
一个加载展示3D动态模型(3D模型格式是.dae)的demo,在google和火狐高版本中运行都没有问题,但是火狐的低版本(比如51,由于项目中需要51版本)中无法兼容代码中相关的es6语法,最后想通过webpack将需要的代码打包出来使用。
问题描述:
代码中使用的一下外部js中都是es6的语法,引入也必须使用import,为了在火狐上兼容,尝试使用webpack+babel实现。
下面记录一下使用webpack和babel的整个过程以及遇到的问题
原因分析:
对babel的使用不熟练
解决方案:
1. 说明:
webpack,默认只能处理一部分ES6新语法,一些更高级处理不了(ES2015+的语法)。需要借助第三方loader来帮忙处理成低级点的语法,再把结果交给webpack打包编译处理。通过Babel可以帮助处理ES6+高级语法,webpack官方文档中指出了loader的作用,即:
2. 安装babel-loader、babel-core、babel-preset-env
上面三个文件,建议安装以下版本的依赖。为什么要指定安装的版本呢,这是由于在使用中,如果不指定版本,可能会由于版本不兼容的问题导致出错。一般babel-loader要比babel/core要高一个版本,即前者是8.x.x,后者就需要是7.x.x,若前是7,后版本就是6。
作用解释:
babel-loader的作用是实现对使用了ES2015+语法的.js文件进行处理;
babel-core的作用在于提供一系列api。这便是说,当webpack使用babel-loader处理文件时,babel-loader实际上调用了babel-core的api,因此也必须安装babel-core;
babel-preset-env的作用是告诉babel使用哪种转码规则进行文件处理。
安装命令为:
3. 配置babel规则
上面仅仅是安装了三个包,如果要使babel起作用,还需要配置babel规则。
第一种方式是通过package.json。在package.json文件中增加一个“babel"属性,该属性是一个JSON对象,作用是设置项目中的babel转码规则和使用到的babel插件,配置如下:
其中: ''presets"属性字段设定转码规则,“plugins"属性设置使用到的插件,
上面的设置告诉npm本项目将使用babel,并且使用bable-preset-env规则进行转码,即实现对ES2015+语法进行转码。
除此之外,第二种方式,即通过.babelrc文件。在项目根目录下新建.babelrc文件,里面只需输入第一种方式中"babel"属性的值即可:
第三种方式:还可以直接在webpack.config.js 文件中配置。就是可以不在package.json文件中配置babel属性。配置如下:
4. 建立并配置webpack.config.js文件
虽然上面已经配置好babel的规则,但webpack仍然不知道何时使用该规则,这便需要使用webpack.config.js文件。
这个文件的作用是对webpack打包的参数进行配置。webpack4.x中webpack.config.js这样的配置文件不是必须的,但事实上,如果想要进行更加个性化的打包配置,仍然要使用该文件。在根目录下自己新建webpack.config.js文件,在其中输入:
这就告诉webpack打包时,一旦匹配到.js文件就使用babel-loader进行处理,如前文所述,babel-loader调用babel-core的api使用bable-preset-env的规则进行转码。这里并没有使用entry、output这样的参数,这是因为webpack4.x的版本有默认的入口和出口,本项目无须改变,因此便不必进行设置。
我的项目名是myDemo,其中默认的入口是myDemo/src/index.js文件,出口文件是src同目录下的: dist/main.js 文件。
意思就是将index.js中内容以及其中引用的文件按照配置规则打包到了main.js文件中。然后我就将这个main.js 拿出来在自己的index.html中引用了,就不会有浏览器兼容问题了。
5. 运行查看结果
我已经在package.json文件的"scripts"属性下增加了"build"属性,然后可以直接执行 npm run build 命令进行打包,不配置可以直接执行冒号后面对应的命令,下面截图分别配置的是生产环境和开发环境。
执行完成之后(warning提示是因为打包生成的main.js超出了大小限制,不影响,也可以自行查看如何配置一下,消除提示),在dist目录下生成了main.js文件,在自己的index.html中引用后,在火狐浏览器打开index.html文件查看。
打开index.html,执行中,在F12中发现还有提示有es6语法存在,无法执行的错误,然后打开main.js文件浏览一下,发现class关键字的存在。此时在网上查找,发现还需要安装@babel/plugin-proposal-class-properties,用来编译类(class)。
先配置在package.json中的依赖中,然后安装。
安装:npm install --save-dev @babel/plugin-proposal-class-properties,之后再把这个配置到babel规则的插件属性下。上面有完成的package.json的完成截图,可参考。
这个问题解决之后又出现: 报错regeneratorRuntime is not defined,
百度得知:Babel在转化一些包的时候,比如说ES6转ES5,需要使用一些辅助函数,这些辅助函数就在babel-runtime这个单独的模块中,当缺失这个单独模块的时候他就会报错,我们需要去下载这个包。
安装命令:npm install --save-dev @babel/plugin-transform-runtime
到此,我的demo就可以在火狐51版本上正常跑起来了。