最近做的一个项目,因涉及到3D的部分功能,由于公司没有这方面经验的人,同是项目比较赶。领导将这部分业务外包给了一个公司做。

这块功能用的是three.js做的,在本公司的的项目里用了iframe引入。所以自己项目的webpack也没有对这部分压缩和转码。

要上线的时候突然发现甲方公司那里的流览器打不开3D这一块。跟根错误发现是3D的业务代码没有进行babel转换。

涉及到很多类的属写法不被旧版chrome支持

class Example {
    aProp = { x: 100 }
    constructor(){ ... }
}

由于这部分业务已经签收了,考虑到利益问题,只能本BUG制作者接下这个锅。

开始

原理

3D部分代码里面是一个个的html文件,html文件中引用了其他的js文件。简单的做法就是用webpack从入口的js文件开始打包和转换,最后只生成一个js,将这个js引用到相应的html文件中。

webpack环境搭建

将3D相关代码复制出来,存放在一个文件夹

// 初始化
npm init -y

// 安装依赖
yarn add webpack webpack-cli --save-dev

目录结构如下:

 webpack-3d
  |- package.json
+ |- /src
+   |- index.js
+   |- index.html
+   |- xxx.js
+   |- xxx.js
+ |- webpack.config.js

其中,index.jsindex.html的入口文件,各个xxx.js是相应的导入依赖。

webpack.config.js是webpack的配置文件,在这量设定入口和输出文件及相应的loader

const path = require('path')

module.exports = {
  // 设写环境为none,不然打包时会发警告
  mode: 'none',
  entry: {
    index: './src/index.js', // 第一个html的入口文件
    customs: './src/customs.js'    // 第二个html的入口文件
  },
  output: {
    filename: '[name].[chunkhash].js', // 输出文件名,后面接上16位hash
    path: path.resolve(__dirname, 'dist') // 输出的文件夹
  },
  module: {
    // 本次的目的,进行babel的转换
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
    ]
  }
}

按装一下需要的loader

// babel的转换一般需要三个转换器

yarn add @babel/core@7.4.5 @babel/preset-env@7.4.5 babel-loader -D

同时需要特别注意,因为项目中用了ES6的class相关方法,还要按装一下@babel/plugin-proposal-class-properties

yarn add @babel/plugin-proposal-class-properties -D

在项目跟目录下新建.babelrc文件

写入以下内容

{
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "browsers": [
            "last 2 versions",
            "not ie <= 9"
          ]
        }
      }
    ]
  ],
  "plugins": [
    ["@babel/plugin-proposal-class-properties", { "loose": true }]
  ]
}

最后在终端运行

npx webpack

即可将entry里面的各个入口文件相应地转码并打包成一个js文件,在相应的html文件引入即可

2020-06-17更新自动引入到html文件功能

自动将打包后的js文件引用html中也是比较简单,只需要一个插件就行了: html-webpack-plugin

yarn add --dev html-webpack-plugin

为了方便演示直接在webpack.config.js文件修改

// webpack.config.js 原有两个入口的js
module.exports = {
  entry: {
    index: './src/index.js', // 第一个js
    customs: './src/customs.js'    // 第二个js
  },
...

引入html-webpack-plugin新建plugins属性

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    ...
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './static/customs-3d-son/index.html',
            chunks: ['index'],
            minify: {
                removeComments: false,
                collapseWhitespace: false,
                removeAttributeQuotes: false,
                minifyJS: false,
                minifyCSS: false
            },
            chunksSortMode: 'auto'
        }),
        // 第二个页面的plugin,如果页面很多,可以使用函数返回多个处理。
        new HtmlWebpackPlugin({
            filename: 'customs.html',
            template: './static/customs-3d-son/customs.html',
            chunks: ['customs'],
            minify: {
                removeComments: false,
                collapseWhitespace: false,
                removeAttributeQuotes: false,
                minifyJS: false,
                minifyCSS: false
            },
            chunksSortMode: 'auto'
        })
    ]
}

大功告成


maYunLaoXi
65 声望3 粉丝

前端开发工程师,自由摄影师