欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

怎样将ES6 bare module引入到本地程序中,3DTilesRendererJS集成问题解决方案探索

程序员文章站 2022-05-03 12:50:03
...

最近想要将NASA的3DTile的解析渲染代码集成到自己的程序中,在github中clone了

git+https://github.com/NASA-AMMOS/3DTilesRendererJS.git 相关代码

在运行其示范代码时却出现以下问题:

“Uncaught SyntaxError: Cannot use import statement outside a module”

因为引用文件引入了class,这是ES6中module中定义的概念,需要在script中加入 type=“module”才能确保浏览器正确解析脚本,如下:

<script src="./customMaterial.js" type="module"></script>

 

虽然浏览器可以解析脚本了,紧接着运行又出现以下报错

“Uncaught SyntaxError: Cannot use import statement outside a module” when importing ECMAScript 6

查阅资料才发现原因:

从第三方导入ES6模块时,仅使用浏览器同步是行不通的。

因为采用import导入相关模块时采用了bare import,如:

import { LineSegments, BufferGeometry, Vector3, BufferAttribute, LineBasicMaterial } from 'three';

如:上面导入的‘three’,

 bare import是使用像Webpack这样的捆绑器时通常会看到的导入,它不是指向node_modules的相对路径,而是映射到了打包发布的路径,例如 通过Webpack打包发布后是可以正常工作的, 但是,如果直接在浏览器中运行,则会看到:

Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".

解决方案:

1)直接引用在线库,某些库都有在线打包发布的地址:

import * from "https://code.jquery.com/jquery-3.1.1.min.js"

2)用Webpack进行打包,这个比较麻烦

  1. `npm install --save-dev webpack webpack-cli copy-webpack-plugin webpack-dev-server `

  2. Create webpack.config.js:

    const path = require('path');
    const CopyPlugin = require('copy-webpack-plugin');
    
    module.exports = {
        entry: './src/app.js',
        mode: 'development',
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'app.js'
        },
        devServer: {
            contentBase: './dist'
        },
        plugins: [
            new CopyPlugin([
                { from: 'src/index.html', to: './' },
                { from: 'src/style.css', to: './' },
            ]),
        ],
    };
  3. Add a script to the package.json"dev": "webpack-dev-server --open"

  4. The import can now look like this:

    import { html, LitElement } from 'lit-element/lit-element.js';

Run the dev-server with live-reload (similar to browser-sync) with npm run dev.

After trying it for a small application and really only doing the bare minimum with Webpack, I have to say it is a viable option. But it requires to download some dependencies from NPM and create a webpack.config.js.

3)Open Web Components (OWC)

Open Web Components offer a simple dev-server that does nothing more than rewrite the bar module imports to relative imports.

npm install --save-dev owc-dev-server

After trying it out, I was disappointed to find that the dev-server does not offer live-reloading.

The best solution I found was to combine it with browser-sync. Here are the scripts I added to my package.json

"dev": "owc-dev-server | npm run watch",
"watch": "browser-sync start -f src/ --proxy localhost:8080 --startPath src",

Note that watch is just a helper-script used by dev; so you have to use npm run dev.

4)Polymer-cli

The last tool I tried was Polymer-CLI. In the end, the approach is a mix between the previous two. It requires an additional polymer.json config-file and it also does not function without browser-sync.

The steps are:

  1. npm install --save-dev polymer-cli

  2. Create polymer.json:

    {
        "entrypoint": "src/index.html",
        "shell": "src/app.js",
        "npm": true
    }
  3. Set up scripts:

    "watch": "browser-sync start -f src/ --proxy localhost:8000 --startPath src",
    "dev": "polymer serve --open-path src/index.html | npm run watch"

以上这些方法可参考:http://dplatz.de/blog/2019/es6-bare-imports.html