阅读 154

Webpack基础应用篇-[10]1.7 使用 babel-loader

前面的章节里,我们应用 less-loader编译过 less 文件,应用 xml-loader编译过 xml 文件,那 js 文件需要编译吗?我们来做一个实验,修改 hello-world.js文件:

08-babel-loader/src/hello-world.js

function getString() {
return new Promise((resolve, reject) => {
   setTimeout(() => {
      resolve('Hello world~~~')
   }, 2000)
})
}

async function helloWorld() {
let string = await getString()
console.log(string)
}

// 导出函数模块
export default helloWorld复制代码

执行编译:

[felix] 08-babel-loader $ npx webpack复制代码

img-1.6.1-1.png

查看 bundle.js 文件:

08-babel-loader/dist/bundle.js

//...

/***/
"./src/hello-world.js":
/*!****************************!*\
!*** ./src/hello-world.js ***!
****************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
   /* harmony export */
   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
   /* harmony export */
});

function getString() {
   return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('Hello world~~~')
      }, 2000)
   })
}

async function helloWorld() {
   let string = await getString()
   console.log(string)
}

// 导出函数模块
/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = (helloWorld);

/***/
}),

//...复制代码

我们发现,编写的ES6代码原样输出了。启动服务,打开浏览器:

[felix] 08-babel-loader $ npx webpack serve复制代码

img-1.5.6-2.png

1.7.1 为什么需要 babel-loader

webpack 自身可以自动加载JS文件,就像加载JSON文件一样,无需任何 loader。可是,加载的JS文件会原样输出,即使你的JS文件里包含ES6+的代码,也不会做任何的转化。这时我们就需要Babel来帮忙。Babel 是一个 JavaScript 编译器,可以将ES6+转化成ES5。在Webpack里使用Babel,需要使用 babel-loader

1.7.2 使用 babel-loader

安装:

npm install -D babel-loader @babel/core @babel/preset-env复制代码
  • babel-loader: 在webpack里应用 babel 解析ES6的桥梁

  • @babel/core: babel核心模块

  • @babel/preset-env: babel预设,一组 babel 插件的集合

在 webpack 配置中,需要将 babel-loader 添加到 module 列表中,就像下面这样:

module: {
  rules: [
    {
      test: /.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }
  ]
}复制代码

执行编译:

[felix] 08-babel-loader $ npx webpack复制代码

查看 bundle.js 文件:

08-babel-loader/dist/bundle.js

/***/
"./src/hello-world.js":
/*!****************************!*\
!*** ./src/hello-world.js ***!
****************************/
/***/
((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */
});

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
 var info = gen[key](arg);
 var value = info.value;
} catch (error) {
 reject(error);
 return;
}
if (info.done) {
 resolve(value);
} else {
 Promise.resolve(value).then(_next, _throw);
}
}

function _asyncToGenerator(fn) {
return function () {
 var self = this,
   args = arguments;
 return new Promise(function (resolve, reject) {
   var gen = fn.apply(self, args);

   function _next(value) {
     asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
   }

   function _throw(err) {
     asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
   }
   _next(undefined);
 });
};
}

function getString() {
return new Promise(function (resolve, reject) {
 setTimeout(function () {
   resolve('Hello world~~~');
 }, 2000);
});
}

function helloWorld() {
return _helloWorld.apply(this, arguments);
} // 导出函数模块


function _helloWorld() {
_helloWorld = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee() {
 var string;
 return regeneratorRuntime.wrap(function _callee$(_context) {
   while (1) {
     switch (_context.prev = _context.next) {
       case 0:
         _context.next = 2;
         return getString();

       case 2:
         string = _context.sent;
         console.log(string);

       case 4:
       case "end":
         return _context.stop();
     }
   }
 }, _callee);
}));
return _helloWorld.apply(this, arguments);
}

/* harmony default export */
const __WEBPACK_DEFAULT_EXPORT__ = (helloWorld);

/***/
}),复制代码

从编译完的结果可以看出,async/await 的ES6语法被 babel编译了。

1.7.3 regeneratorRuntime 插件

此时执行编译,在浏览器里打开项目发现报了一个致命错误:

img-1.6.3-1.png

regeneratorRuntime是webpack打包生成的全局辅助函数,由babel生成,用于兼容async/await的语法。

regeneratorRuntime is not defined这个错误显然是未能正确配置babel。

正确的做法需要添加以下的插件和配置: /# 这个包中包含了regeneratorRuntime,运行时需要 npm install --save @babel/runtime

/# 这个插件会在需要regeneratorRuntime的地方自动require导包,编译时需要 npm install --save-dev @babel/plugin-transform-runtime

/# 更多参考这里babeljs.io/docs/en/bab…

接着改一下babel的配置:

module: {
  rules: [
    {
      test: /.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
          plugins: [
            [
              '@babel/plugin-transform-runtime'
            ]
          ]
        }
      }
    }
  ]
}复制代码

08-babel-loade/webpack.config.js

//...

module.exports = {
//...

// 配置资源文件
module: {
rules: [{
   test: /.js$/,
   exclude: /node_modules/,
     use: {
     loader: 'babel-loader',
       options: {
           presets: ['@babel/preset-env'],
       plugins: [
             [
               '@babel/plugin-transform-runtime'
         ]
           ]
         }
   }
     },

 //...
 ],
},

//...
}复制代码

启动服务,打开浏览器:

img-1.6.3-2.png


作者:锋享前端
链接:https://juejin.cn/post/7054453009878614023


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐