babel使用详解

242 阅读5分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

Babel

Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

首先,我们可以直接通过命令行来安装和使用babel。并不一定需要在webpack中使用,babel是一个独立的工具。

安装:

  1. @babel/core 是babel的核心代码,我们必须安装
  2. @babel/cli 是为了在命令行中使用
 npm install @babel/cli @babel/core -D

一、使用babel处理文件夹、

  • src表示源文件目录
  • dist表示输出的文件夹
 npx babel src --out-dir dist

二、使用babel处理文件

  • src/component.js表示源文件
  • dist/component.js表示转换后输出的文件
 npx babel src/component.js --out-file dist/component.js

实际上这样执行命令后,我们的文件是没有被转换的,因为babel是依赖于插件的,我们需要安装相应的插件,来处理我们代码。

例如:处理箭头函数插件,处理const和let,将其转为var。

安装插件:

 //处理箭头函数
 npm install @babel/plugin-transform-arrow-functions -D
 ​
 //处理let和const
 npm install @babel/plugin-transform-block-scoping -D

执行命令:使用插件

 npx babel src --out-dir dist --plugins=@babel/plugin-transform-block-scoping
 ,@babel/plugin-transform-arrow-functions

现在我们可以使用插件来实现对应代码的处理,但是我们不难发现,为了处理不同的语法,我们需要安装非常多的插件。使用也非常的不方便,因此我们可以使用babel的预设preset。

preset就是集成了很多常用的插件,我们不需要一个一个的安装,直接使用预设就可以对我们的代码进行处理了。

安装预设:

 npm install @babel/preset-env -D

使用preset:

 npx babel src --out-dir dist --presets=@babel/preset-env

babel原理

实际上,babel可以看成一个编译器,将我们编写的(es6,Typescript,React)转成es5代码。

转化的步骤:

  1. 解析阶段
  2. 转换阶段
  3. 生成阶段

编译器工具工作流程:

image-20220206164021018.png

webpack使用babel

安装babel和babel-loader

 npm install babel-loader @babel/core

安装相应的插件:

 //处理箭头函数
 npm install @babel/plugin-transform-arrow-functions -D
 ​
 //处理let和const
 npm install @babel/plugin-transform-block-scoping -D

配置webpack:处理js文件时,使用babel-loader

  {
         test: /.js$/,
         use: [
           {
             loader: "babel-loader",
             options: {
               plugins: [
                 "@babel/plugin-transform-arrow-functions",
                 "@babel/plugin-transform-block-scoping",
               ],
             },
           },
         ],
       },

我们也可以使用preset-env,常用的有三种:

  1. @babel/preset-env
  2. @babel/preset-react
  3. @babel/preset-typescript

安装preset:

 npm install @babel/preset-env

在webpack中配置preset

 {
         test: /.js$/,
         use: [
           {
             loader: "babel-loader",
             options: {
               presets: ["@babel/preset-env"],
             },
           },
         ],
       },

我还可以在独立的文件中配置bable,文件名有两种:

  1. babel.config.json(或者.js,.cjs,.mjs)文件;Monorepos项目中使用较多。
  2. .babelrc.json(或者.babelrc,.js,.cjs,.mjs)文件;老项目中使用较多。

这里我通过babel.config.js文件进行配置:

 module.exports = {
   presets: ["@babel/preset-env"],
 };

打包vue代码

首先,我们肯定要安装vue,这里我们使用vue3

 npm install vue@next

在js文件中编写vue代码:

 import "./js/component";
 console.log("执行代码");
 ​
 import {createApp} from "vue/dist/vue.esm-bundler.js";
 ​
 const app = createApp({
   template: "#my-app",
   data() {
     return {
       name: "王",
     };
   },
 });
 app.mount("#app");

模板写在index.html文件中:

 <!DOCTYPE html>
 <html lang="">
   <head>
     <meta charset="utf-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width,initial-scale=1.0" />
     <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
     <title><%= htmlWebpackPlugin.options.title %></title>
   </head>
   <body>
     <div id="app"></div>
     <!-- built files will be auto injected -->
 ​
     <template id="my-app"
       ><div>我是vue渲染出来的</div>
       <div>{{name}}</div>
     </template>
   </body>
 </html>
 ​

此时,我们运行代码,在控制台中会看件两个警告,并且vue代码是不能正常显示的。

image-20220206172511267.png

第一个警告:表示建议我们配置 VUE_OPTIONS_API__ , VUE_PROD_DEVTOOLS标识符。

VUE_OPTIONS_API__ 表示是否支持options API,options API是vue2中的写法。

__VUE_PROD_DEVTOOLS__ 表示是否在生产模式下启用或者禁用devtools工具。

第二个警告:表示我们现在使用的是runtime compilation的vue,是不能解析template模板的,因此出错了。建议我们使用vue.esm-bundler.js(包含编译器的vue文件)

接下来,我们来解决这两个问题:

解决警告一:在webpack.config.js文件中配置DefinePlugin插件,设置两个tag的值即可。

  new DefinePlugin({
       __VUE_OPTIONS_API__: true,
       __VUE_PROD_DEVTOOLS__: false,
     }),

解决警告二:导入使用vue.esm-bundler.js文件

 import {createApp} from "vue/dist/vue.esm-bundler";

vue打包后不同版本解析

vue(.runtime).global(.prod).js:

  • 通过浏览器中的
  • 我们之前通过CDN引入和下载的Vue版本就是这个版本;
  • 会暴露一个全局的Vue来使用;

vue(.runtime).esm-browser(.prod).js:

  • 用于通过原生 ES 模块导入使用 (在浏览器中通过

vue(.runtime).esm-bundler.js:

  • 用于 webpack,rollup 和 parcel 等构建工具;
  • 构建工具中默认是vue.runtime.esm-bundler.js;
  • 如果我们需要解析模板template,那么需要手动指定vue.esm-bundler.js;

vue.cjs(.prod).js:

  • 服务器端渲染使用;
  • 通过require()在Node.js中使用;

运行时+编译器VS 仅运行时

在Vue的开发过程中我们有三种方式来编写DOM元素:

  • 方式一:template模板的方式(之前经常使用的方式);
  • 方式二:render函数的方式,使用h函数来编写渲染的内容;
  • 方式三:通过.vue文件中的template来编写模板;

它们的模板分别是如何处理的呢?

  • 方式二中的h函数可以直接返回一个虚拟节点,也就是Vnode节点

  • 方式一和方式三的template都需要有特定的代码来对其进行解析:

    方式三.vue文件中的template可以通过在vue-loader对其进行编译和处理;

    方式一种的template我们必须要通过源码中一部分代码来进行编译;

所以,Vue在让我们选择版本的时候分为 运行时+编译器 vs 仅运行时

  • 运行时+编译器包含了对template模板的编译代码,更加完整,但是也更大一些;
  • 仅运行时没有包含对template版本的编译代码,相对更小一些;

编写sfc文件

我们要处理app.vue文件,我们需要使用vue-loader来进行加载.vue文件。

安装:因为我们使用的是vue3,因此需要安装vue-loader@next,vue2使用vue-loader

 npm install vue-loader@next -D

然后在webpack.config.js中配置:

 {
     test: /.vue$/,
     use: "vue-loader",
 },

还需要配置vue插件:

 const {VueLoaderPlugin} = require("vue-loader/dist/index");
 module.exports={
     plugins:[
         new VueLoaderPlugin(),
     ]
 }

最后,我们还需要安装 @vue/compiler-sfc,必须由 @vue/compiler-sfc 预编译为标准的 JavaScript 与 CSS。编译后的 SFC 是一个标准的 JavaScript(ES)模块。

 npm install @vue/compiler-sfc -D