简体   繁体   中英

three.js ES6 how import only specific modules

I've installed three.js library through NPM to get advantage of the new ES6 modular architecture which should let you to import just the modules you need, as explained here: Threejs - Import via modules .

I am using gulp , browserify and babel for bundling and transpiling, like so:

gulp.task("build_js", () => {

return browserify({
    entries: "./public/app/app.js",
    cache: {},
    dev: true
})
    .transform(babelify, {presets: ["env"], plugins: ["syntax-async-functions", "transform-async-to-generator"], sourceMaps: true})
    .bundle()
    .pipe(source("app.bundle.min.js"))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: mode}))
    .pipe(uglify())
    .pipe(sourcemaps.write("./"))
    .pipe(gulp.dest(config.build.js))

});

I want to import only the modules I need and keep the bundle size small, but I noticed that the bundle generated by browserify has the same size regardless if I import all the modules or just one.

If in app.js I import all the modules I got a bundle size of about 500Kb:

// app.js

import * as THREE from 'three'; // about 500 Kb size

But if I try to import just a specific module using ES6 syntax I got the same bundle size (it is importing again all the modules):

// app.js

import { Vector3 } from 'three'; // about 500 Kb size, same as before example

I've also tried the following:

// app.js

import { Vector3 } from "three/build/three.module.js";

But I got the following error:

SyntaxError: 'import' and 'export' may only appear at the top level (45590:0) while parsing /Users/revy/proj001/node_modules/three/build/three.module.js

My question: how can I properly import only the modules I need and keep the bundle size small?

You are missing the concept of Tree Shaking .

When you import a modules by name the other modules are not automatically removed from the bundle. The bundler always includes every module in the code and ignores what you have specified as import names.

The other unused modules, which you did not import, are considered dead code because they are in the bundle however they are not called by your code.

So to remove this unused code from the bundle and thus make the bundle smaller you need a minifier that supports dead code removal.

Check out this popular tree shaking plugin for browserify - it should get you started:

https://github.com/browserify/common-shakeify

Solved using rollupify inside browserify transform. It will perform tree shaking and remove dead code:

gulp.task("build_js", () => {

return browserify({
    entries: "./public/app/app.js",
    cache: {},
    dev: true
})
    .transform(rollupify, {config: {}})    // <---
    .transform(babelify, {presets: ["env"], plugins: ["syntax-async-functions", "transform-async-to-generator"], sourceMaps: true})
    .bundle()
    .pipe(source("app.bundle.min.js"))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: mode}))
    .pipe(uglify())
    .pipe(sourcemaps.write("./"))
    .pipe(gulp.dest(config.build.js))

});

}

Still I would appreciated an explanation on why ES6 module import works like this..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM