美文网首页webapck 4.x
webpack 处理ES6语法(8)

webpack 处理ES6语法(8)

作者: 瓦力博客 | 来源:发表于2019-06-10 17:47 被阅读12次

获取全套webpack 4.x教程,请访问瓦力博客

为什么要处理ES6语法呢?当我们使用新语法来写代码,一些浏览器如果不支持那么就会报错,导致用户体验非常糟糕。我们使用babel来将ES6语法处理成ES5语法,就可以解决这个问题。

1.安装Babel

yarn add babel-loader @babel/core

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');    //生成html文件
const CleanWebpackPlugin = require('clean-webpack-plugin');  //清除



module.exports = {
  mode:'development',
  entry:'./src/index.js',
  module:{
    rules:[
        {
            test:/\.css$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:1
                    }                   
                },
                'postcss-loader'
                
            ]
        },
        {
            test:/\.scss$/,
            use:[
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'sass-loader',
                'postcss-loader'
            ]
        },
        {
            test: /\.less$/,
            use: [
                'style-loader',
                {
                    loader:'css-loader',
                    options:{
                        importLoaders:2
                    }                   
                },
                'less-loader',
                'postcss-loader'
            ]
        },
        {
            test:/\.(png|svg|jpeg|jpg|gif)$/,
            use:[       
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文环境路径
                        publicPath:'./assets/image/',    //公共路径
                        outputPath:'assets/image/',  //输出路径                         
                    }
                },
                {
                    loader: 'image-webpack-loader',
                    options: {
                        bypassOnDebug: true, // webpack@1.x
                        disable: true,       // webpack@2.x and newer
                    },
                },
            ]
        },
        {
            test: /\.html$/,
            use:[
                {
                    loader:'html-loader',
                    options:{
                        arrts:['img:src','img:data-src'],
                        minimize:false  //是否压缩html
                    }
                }
            ]
        },
        {
            test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
            use:[
                {
                    loader:'file-loader',
                    options:{
                        name:'[name].[ext]',  //[path] 上下文环境路径
                        publicPath:'./assets/iconfont/',    //公共路径
                        outputPath:'assets/iconfont/',  //输出路径                          
                    }
                }               
            ]
        },
+       {
+           test: /\.js$/,
+           exclude: /(node_modules|bower_components|lib)/,
+           loader: 'babel-loader'
+       }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
        title: '瓦力博客',
        template: './src/index.html'   //以src/index.html为编译模板
    }),
    new CleanWebpackPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer:{
    contentBase: path.join(__dirname, 'dist'),
    clientLogLevel: 'info',
    open:true,  //启动时默认打开浏览器
    host:'localhost', //域名 0.0.0.0局域网可访问
    port:'9009',
    inline:true, //实时更新
    hot:true,    //热替换
    hotOnly:true,
    proxy:{
        '/':{
            target:'http://www.waliblog.com'
        },
        '/upload':{
            target:'http://www.waliblog.com'
        }
    }
  },
  output:{
    path: path.resolve(__dirname,'dist')
  }
}

文件结构

myProject
 |-dist
 |-node_modules
 |-src
     |-assets
        |-css
            |-index.css
        |-less
            |-index.less     
        |-sass
            |-index.scss
        |-images
            |-wali_logo.png
     |-index.html
     |-index.js
 |-package.json
 |-webpack.config.js
 |-postcss.config.js
+ |-.babelrc

安装@babel/preset-env

yarn add @babel/preset-env

.babelrc

{
    "presets": ["@babel/preset-env"]
}

src/index.js

const arr = [
    new Promise(() => {}),
    new Promise(() => {})
]


arr.map(val => {
    console.log(val)
})

package.json

{
  "scripts": {
    "dev": "npx webpack-dev-server --mode=development --colors",
    "dist": "npx webpack --mode=production",
+    "build": "npx webpack --mode=development --colors"
  }
}

运行webpack

yarn run build

打包完成后我们打开dist目录下main.js,最下面能后找到

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/*! no static exports found */
/***/ (function(module, exports) {

eval("var arr = [new Promise(function () {}), new Promise(function () {})];\narr.map(function (val) {\n  console.log(val);\n});\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ })

我们看到ES6语法被转换成了ES5语法,但是只转换了一部分,比如在低版本浏览中还是识别不了PromiseMap这样的语法。

2.兼容低版本浏览器

安装babel/polyfill

yarn add @babel/polyfill

src/index.js

+ import "@babel/polyfill";
const arr = [
    new Promise(() => {}),
    new Promise(() => {})
]


arr.map(val => {
    console.log(val)
})

运行webpack

yarn run build
ssl
//dist/main.js
/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/*! no exports provided */
/*! all exports used */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _babel_polyfill__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/polyfill */ \"./node_modules/@babel/polyfill/lib/index.js\");\n/* harmony import */ var _babel_polyfill__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_polyfill__WEBPACK_IMPORTED_MODULE_0__);\n\nvar arr = [new Promise(function () {}), new Promise(function () {})];\narr.map(function (val) {\n  console.log(val);\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvaW5kZXguanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvaW5kZXguanM/MzcwMCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgXCJAYmFiZWwvcG9seWZpbGxcIjtcbnZhciBhcnIgPSBbbmV3IFByb21pc2UoZnVuY3Rpb24gKCkge30pLCBuZXcgUHJvbWlzZShmdW5jdGlvbiAoKSB7fSldO1xuYXJyLm1hcChmdW5jdGlvbiAodmFsKSB7XG4gIGNvbnNvbGUubG9nKHZhbCk7XG59KTsiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/index.js\n");

/***/ })

从webpack打包输出的信息中可以看到,PromiseMap方法@babel/polyfill自己帮我们做了实现。可是dist/mian.js文件突然增大到941kb,原因就是
main.js文件将整个polyfill都打包进来。我们想要的其实在main.js中用到的方法帮助我们实现,如果没有用到,就不需要打包进main.js。

3.精简代码

.babelrc

{
  "presets": [
        [
            "@babel/preset-env",
+           {
+               "useBuiltIns": "usage"
            }
        ]
    ]
}

运行webpack

yarn run build
ssl

当我们在.babelrc文件中配置"useBuiltIns": "usage",我们发现打包出来的main.js文件大小变成29kb。"useBuiltIns": "usage"作用就是当polyfill去往低版本浏览器添加一些特性的时候,不是把所有的特性都加进了,而是根据你的业务代码来决定添加什么。

4.设置浏览器版本

.babelrc

{
  "presets": [
        [
            "@babel/preset-env",
+           {
+               "targets": {
+                   "edge": "17",
+                   "firefox": "60",
+                   "safari": "11.1",
+                   "chrome": "67"
+               },
+               "useBuiltIns": "usage"
            }
        ]
    ]
}

"chrome": "67"指编译的代码要运行在67版本的chrom浏览器上,如果67版本chrom支持promis等新语法,则不转换,否则进行转换。

运行webpack

yarn run build

5.插件开发

上面教程如果我们开发项目,完全够用了。但是当我们开发插件时就会有问题,因为上面是将promis等新特性的实现通过全局变量来注入,会污染全局环境。而且写代码还要在js前面添加import "@babel/polyfill"。所以小菜建议下面这种方式

安装pluginTransformRuntime

yarn add @babel/plugin-transform-runtime
yarn add @babel/runtime
yarn add @babel/runtime-corejs2

.babelrc

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "targets": {
                    "chrome": "67"
                },
                "useBuiltIns": "usage"
            }
        ]
    ],
+  "plugins": [
+    [
+      "@babel/plugin-transform-runtime",
+      {
+        "absoluteRuntime": false,
+        "corejs": 2,
+        "helpers": true,
+        "regenerator": true,
+        "useESModules": false
+      }
+    ]
+  ]
}

运行webpack

yarn run build

打开dist/main.js文件

/***/ "./src/index.js":
/*!**********************!*\
  !*** ./src/index.js ***!
  \**********************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/promise */ \"./node_modules/@babel/runtime-corejs2/core-js/promise.js\");\n/* harmony import */ var _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0__);\n\nconst arr = [new _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0___default.a(() => {}), new _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0___default.a(() => {})];\narr.map(val => {\n  console.log(val);\n});\n\n//# sourceURL=webpack:///./src/index.js?");

/***/ })

从打包的代码我们可以看到,向PromiseMap都帮助我们实现了。

相关文章

  • webpack 处理ES6语法(8)

    获取全套webpack 4.x教程,请访问瓦力博客 为什么要处理ES6语法呢?当我们使用新语法来写代码,一些浏览器...

  • Webpack4 快速上手

    Webpack 基础 为什么要使用Webpack 转换ES6语法 转换JSX CSS前缀补全/预处理器 压缩整合 ...

  • webpack的ES6支持与Babel

    Babel安装与说明 在webpack中只能处理一部分ES6语法,一些更高级的ES6或ES7语法不能处理,这是就需...

  • 2.如何安装babel解析es6高级语法

    Babel解析es6语法,主要分为3步:在 webpack 中,默认只能处理 一部分 ES6 的新语法,一些更高级...

  • webpack1/2/3区别

    一、 Webpack2 VS Webpack1新增了许多新特性,需要处理配置语法兼容 增加对 ES6 模块的原生支...

  • webpack4中Babel配置

    一、说明webpack,默认只能处理一部分ES6新语法,一些更高级处理不了(ES2015+的语法)。需要借助第三方...

  • web前端各浏览器兼容性问题

    对 ES 语法的支持上 ES6 的兼容问题项目打包的时候 webpack 中用 babel-loader 处理 F...

  • webpack4实战记录

    webpack4/rollup/parcel 为什么要构建工具?转化es6语法转化jsxCss前缀补全/预处理器压...

  • 8-9月任务

    整理 ES6脑图,相关语法 vue源码分析image.png webpack原理分析,常用api学习 文章 V8引...

  • webpack工程化02(使用babel)

    webpack大部分的功能都是通过loader和plugin来实现的,接下来讲一下如何处理es6语法,babel的...

网友评论

    本文标题:webpack 处理ES6语法(8)

    本文链接:https://www.haomeiwen.com/subject/dhrtfctx.html