webpack入门 ~Babel,Polyfill为你带来美好的ES6体验~

aki发表于:2020年08月31日 13:52:53更新于:2021年04月20日 15:12:55

概要

在进行kintone的JavaScript开发时,我想谁都会碰到“在IE11下无法正常运行!”的情况。

遇到这种在个别浏览器上无法运行的问题时,通常的解决方法是使用Babel、Polyfill、webpack这类工具。

本次就向大家介绍这3个工具如何运用于kintone自定义开发。

中间会提到node、npm、npx这些命令。这些在 https://nodejs.org/下载安装包并安装了node.js之后会自动安装。

关于安装方法以及node、npm、npx命令代表的含义此处不做介绍。

关于Babel和Polyfill

JavaScript可以说是与日俱进,现在有ES5、ES6(ES2015)、ES2016等版本,您知道吗?

关于JavaScript的发展有两个方面。

一个是编程语言的扩展,另一个是标准库的扩展。

但是,各浏览器间的支持情况有所不同。参考: 针对ES6的各浏览器支持情况

编程语言的扩展

例如, ES6的JavaScript可以使用模板字符串的语法。

可以在字符串里嵌入变量,字符串中包含换行符也没问题:

const es6Name = "john";    
console.log(`hello ${es6Name} . nice to meet you`);  
  
// ES5    
var name = "john";    
console.log("hello " + name + " . nice to meet you");

是不是感觉轻松多了。但是这个模板字符串IE11不支持,在解析JavaScript时会报错。

Babel就可以帮我们解决这个问题。它可以将ES6的代码转义成ES5下可以运行的代码。

关于代码转义的具体情况请参考Babel的官网。

标准库的扩展

不单是语法,JavaScript的内置对象库也在进化。

例如,ES6增加了Object.values这个非常方便的方法。

const object = {a: "sample", b:42, c:false};    
console.log(Object.values(object)); // output: ["sample", 42, false];

但是这个IE11也不支持。像这样根据浏览器不同,有支持的有不支持的。而能够帮我们解决这个困恼的就是Polyfill。

Polyfill在检测到有方法未封装时,会在导入Polyfill库时自动追加安装。

因为,在IE11等环境下也可以使用Object.values。

polyfill.io服务已作为CDN发布,可以使用这个。

关于webpack

webpack是JavaScript的编译工具,其绑定了在浏览器上运行JavaScript时所必须的库,还可以切换编程语言。

webpack可以对ES6增加的importexport进行解析,然后绑定必要的库和模块。

本文以在webpack中导入Babel和Polyfill后进行操作为例来说明。

以上介绍了工具最基本的知识,接下来我们来实践一下。

教程

课题:使用ES6的语法来封装kintone自定义

1. 使用npm来初始化项目

npm init

以下步骤在项目目录下进行。


2. 安装webpack和Babel等工具

npm install -D webpack webpack-cli webpack-dev-server \    
babel-loader @babel/core @babel/preset-env core-js@3


  • webpack ... webpack主体

  • webpack-cli ... 在命令行内使用webpack的工具

  • webpack-dev-server ... 开发工具,用于在本地服务器上托管正在开发的程序

  • babel-loader ... Babel的webpack插件

  • @babel/core ... Babel主体

  • @babel/preset-env ... Babel的JavaScript转化工具

  • core-js ... 定义了JavaScript的标准库,可导入Polyfill进行使用

 

3. 配置webpack.config.js

在npm init的同一目录下配置webpack.config.js。

const path = require('path');

module.exports = {
  entry: {
      'kintone-create-edit-show': './src/kintone-create-edit-show.js'
  },
  // 如使用的是webpack 5,而且希望也能支持IE,请取消下一行的注释 
  // target: ['web', 'es5'],
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                "@babel/preset-env",
                {
                  useBuiltIns: 'usage',
                  corejs: 3
                }
              ]
            ]
          }
        }
      }
    ]
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  externals: {
    jquery: 'jQuery'
  }
};

webpack.config.js的设置项目:

entry:

指定JavaScript的入口点。如果是kintone自定义,那就是写有kintone.events.on方法的程序。

entry可以设置对象。

范例程序中,设置了kintone-create-edit-show的入口点。

target:

编译后的文件需要指定是针对什么环境的文件,如果不指定,将默认为['web'](参考:target

但是,在webpack 5下编译时,生成的代码不支持IE。如果要webpack 5下编译,且需要支持 IE,请指定['web', 'es5'](即取消上面范例代码的注释)。

module:

编写JavaScript的转换工具。符合test中指定的正则表达时,则运行Babel的转换程序。

本次例子中是当读入符合.js或mjs的文件时,将被设置为“通过Babe自定转换”的对象。

output:

设置用于输出编译后JavaScript的目录。path是输出目录,filename是文件名。

path不太好理解。在存放package.json的目录下有一个dist目录,编译后的JavaScript会放在该目录下。

关于filename的[name],以entry中指定的键名为文件名自动生成。

externals:

kintone的JS自定义中,可以上传的文件大小有限制。

而webpack会将用到的库都打包到同一个文件里,因此应该注意的是用webpack编译后的文件一般会偏大。

externals中指定诸如jQuery等可定义全局变量的这类型库时,即使在代码中import了jQuery,webpack也会将其忽略。

上面介绍了在进行kintone自定义时需要了解的最基本设置项。当然,还有更加复杂的内容,详情请参考webpack文档


4. 使用ES6来进行JS自定义

下面例子是使用ES6中导入的语法和库写的简单程序。

import jQuery from "jquery";
const events = [
    "app.record.create.show",
    "app.record.edit.show",
];
kintone.events.on(events, (ev) => {
    const el = kintone.app.record.getHeaderMenuSpaceElement();
    const hello = "hello";
    const world = "world!";
    const message = {
        hello,
        world,
    };
    const copied = Object.assign({}, message);
    jQuery(el).append(`<div>${copied.hello} ${copied.world}!</div>`);
});

在工作文件夹内准备一个“src”文件夹,将以上代码另存为“kintone-create-edit-show.js”。

※和webpack.config.js的entry点保持一致。


5. 编译

执行以下命令,webpack将对JavaScript进行编译。

  • 可以使用--mode来指定development和production。正在开发的话选择development。

    npx webpack --mode development # 开发    
    # 发布时使用以下命令可以实现自动压缩等    
    # npx webpack --mode production

编译完成后,会在dist目录下生成kintone-create-edit-show.js,将它上传到kintone后确认运行情况。

※ 也有webpack-dev-server这个工具,这个将在其他文章里介绍。


6. 上传

编译后的程序上传到kintone。

上传kintone-create-edit-show.js。这里要注意的是jQuery(本次是 https://js.cybozu.cn/jquery/3.4.1/jquery.min.js)需单独贴链接。

0015f61ab28063e973658b3a649245a

确认一下,可以在IE中运行了吧

在Chrome浏览器的console里确认一下用webpack编译的程序。

可以看到模板字符串已转换。

0015f61ac072c2f5665b5684d211f5a


 7. 体验import和export

通过npm install命令来安装可以转换全角半角的开源库,然后使用import和export来封装代码。

npm install mojin

编写需要转换全角半角的代码,然后export。(src/hankaku.js)

import moji from 'moji';    
export const zenkakuToHankaku = (value) => moji(value).convert('ZE', 'HE').toString();

在写有kintone.events.on的文件里import。(src/kintone-create-edit-submit.js)

import {zenkakuToHankaku} from "./hankaku";

const events = [
    "app.record.create.submit",
    "app.record.edit.submit"
];
kintone.events.on(events, (ev) => {
    if(ev.record.单行文本框.value) {
        ev.record.单行文本框.value = zenkakuToHankaku(ev.record.单行文本框.value);
    }
    return ev;
});

需要修改webpack.config.js。因为在范例代码的仓库(下文)里,因此本次不做演示。

再次编译时,会生成2个文件。

  • 添加记录、编辑记录页面打开时的文件

  • 添加或更新时的事件处理文件

转换全角半角的方法和所使用的库一起绑定在事件处理的文件里。

以上就是本次全部教程。

注意事项: 仅需注意Proxy

Babel的限制事项如下(Babel官网的摘要):

Due to the limitations of ES5, Proxies cannot be transpiled or polyfilled. See support in various JavaScript engines.

从ES5开始就有的Proxy是唯一的限制事项。因此,在IE11下使用Proxy时,会因此报错。
有了webpack,开源库用起来会更加方便。但是在使用库时,以防万一还是要确认一下浏览器的支持情况。

其他小知识点:最近也可以像这样写哦!

最后介绍一下最新的JavaScript中比较值得推荐的几个功能。

constlet

  • 在块作用域里用const定义的变量再代入时会报错

  • 块作用域内用let定义的变量可以再代入

出了块作用域,定义的变量不可用。

模板字符串

可以使用易于插入换行符和变量的语法。

const message = "hello world";    
`    
This is string template.    
${message}.    
`;    
// output:    
//    
// This is string template.    
// hello world.    
//

importexport

是为了实现模块功能而新增的语法。在JavaScript里可以使用模块功能了。

可以不需要定义全局方法,使用模块功能。

如果是kintone自定义,推荐用webpack来编译。

// functions.js    
export function sum(a, b) { return a + b}
import {sum} from './functions';

分割代入

{
    const [a, b] = [10, 20];
    console.log(a); // 10
    console.log(b); // 20
}
{
    const [a, b, ...rest] = [10, 20, 30, 40, 50];
    console.log(a); // 10
    console.log(b); // 20
    console.log(rest); // [30, 40, 50]
}
{
    const ({ a, b } = { a: 10, b: 20 });
    console.log(a); // 10
    console.log(b); // 20
}

现在可以轻松检索数组或对象属性的一些值了。

对象初始化

以前需要传递对象的键名,现在只要把变量直接传递给对象字面量,即可作为对象的属性识别。

const a = 1;    
const b = 2;    
const c = 3;    
const d = {    
  a,    
  b,    
  c,    
  e: "hello!"    
}

箭头函数

函数变得更加简洁。

const sum = (a, b) => a + b;

最后

读了这么长的文章,大家辛苦了。

希望webpack、Babel、Polyfill可以为大家带来更加舒适的JavaScript体验,避免各种开发上的麻烦!

本教程介绍的是每次都进行重新编译。除此之外,也有可自动检测JavaScript是否有更新并自动再编译的功能。
如果能运用到实际开发工作中,将大大节省JavaScript更新的时间。
关于这点,也计划另写文章向大家介绍。敬请期待!

此Tips在2019年2月版的 kintone中确认过。