添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
很拉风的鼠标垫  ·  Webpack is producing ...·  1 周前    · 
玩篮球的黄豆  ·  UI 插件 API | Vue CLI·  1 周前    · 
幸福的芹菜  ·  Need help with ...·  1 周前    · 
微笑的伤痕  ·  编译时配置·  1 周前    · 
绅士的杨桃  ·  java.beans.PropertyDes ...·  5 月前    · 
逃课的消炎药  ·  SQL split-阿里云·  6 月前    · 
不羁的课本  ·  Bibbidi-Bobbidi-Boo - ...·  9 月前    · 

I’ve already successfully built a Cesium app using webpack as outlined inthe following Cesium tutorial: This tutorial explains how to integrate the Cesium npm module from webpack, and explores more advanced webpack configurations for optimizing an application using CesiumJS. – Cesium

I’m now trying to create a similar app using Vue.js. Currently I’m unable to get the Vue.js app to run or build due to the following error:

 ERROR  ReferenceError: path is not defined
ReferenceError: path is not defined
    at Object.<anonymous> (C:\Users\virt\Documents\GitHub_Repositories\Websites\Vue_Cesium_Client\vue_cesium_client\vue.config.js:19:11)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at exports.loadModule (C:\Users\virt\Documents\GitHub_Repositories\Websites\Vue_Cesium_Client\vue_cesium_client\node_modules\@vue\cli-shared-utils\lib\module.js:86:14)
    at loadFileConfig (C:\Users\virt\Documents\GitHub_Repositories\Websites\Vue_Cesium_Client\vue_cesium_client\node_modules\@vue\cli-service\lib\util\loadFileConfig.js:30:20)      
    at Service.loadUserOptions (C:\Users\virt\Documents\GitHub_Repositories\Websites\Vue_Cesium_Client\vue_cesium_client\node_modules\@vue\cli-service\lib\Service.js:339:44)        
PS C:\Users\virt\Documents\GitHub_Repositories\Websites\Vue_Cesium_Client\vue_cesium_client>

Steps to recreate:

  • Install Node.js
  • Use NPM to insall the VUE CLI:
  • npm install -g @vue/cli

  • Create a directory for the project.
  • Navigate to the project folder.
  • Create the Vue project:
  • vue create <project name>

  • Select option ‘Manually select features’.
  • Select ‘Babel’ and deselect ‘Linter/Formatter’ by pressing Space Bar and then Return.
  • Select Vue ‘3.x’.
  • Select to place Babel ‘In dedicated config files’.
  • Enter ‘N’ when prompted to save preset for future projects.
  • Open the project folder in your preferred IDE (e.g. code . for VSCode from the command line).
  • Navigate to the newly created app folder:
  • cd <project_name>

  • Install the Cesium module from npm and add it to package.json:
  • npm install --save-dev cesium

  • Test the build command
  • npm run build

  • Run the development server:
  • npm run serve

  • Add the following to the top of vue.config.js:
  • const { defineConfig } = require("@vue/cli-service");
    // The path to the CesiumJS source code
    const cesiumSource = 'node_modules/cesium/Source';
    const cesiumWorkers = '../Build/Cesium/Workers';
    
  • Update the module.exports section in vue.config.js as follows:
  • module.exports = defineConfig({
      transpileDependencies: true,
      context: __dirname,
      entry: {
        app: "./src/main.js",
      output: {
        filename: "[name].js",
        path: path.resolve(__dirname, "dist"),
      // Add module rules for loading CSS and other files
      module: {
        rules: [
            test: /\.css$/,
            use: ["style-loader", "css-loader"],
            test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
            use: ["url-loader"],
      // Address Webpack compilation issues of Cesium
      output: {
        filename: "[name].js",
        path: path.resolve(__dirname, "dist"),
        // Needed to compile multiline strings in Cesium
        sourcePrefix: "",
      amd: {
        // Enable webpack-friendly use of require in Cesium
        toUrlUndefined: true,
      // Add a Cesium alias that can be referenced in app code
      resolve: {
        alias: {
          // CesiumJS module name
          cesium: path.resolve(__dirname, cesiumSource),
      plugins: [
        new HtmlWebpackPlugin({
          template: "src/index.html",
        // Copy Cesium Assets, Widgets, and Workers to a static directory
        new CopywebpackPlugin({
          patterns: [
            { from: path.join(cesiumSource, cesiumWorkers), to: "Workers" },
            { from: path.join(cesiumSource, "Assets"), to: "Assets" },
            { from: path.join(cesiumSource, "Widgets"), to: "Widgets" },
        new webpack.DefinePlugin({
          // Define relative base path in Cesium for loading assets
          CESIUM_BASE_URL: JSON.stringify(""),
        new Dotenv(),
    
  • Rerun the development server:
  • npm run serve.

    My assumption is that the vue.config.js file should accept the webpack configuration but I’m unsure how to implement this properly. Vue provide the following guidance ( Working with Webpack | Vue CLI ) but I’m unclear how that applies in this instance. Any advice appreciated.

    Hi @virtualarchitectures,

    I was able to get CesiumJS up and running in a Vue app by following these steps:

  • Install the following dependencies:
  • npm i cesium # This should be a dependency, not a devDependency
    npm i --save-dev copy-webpack-plugin
    npm i --save-dev webpack
    
  • Configure your vue.config.js file as follows:
  • const { defineConfig } = require("@vue/cli-service");
    const path = require("path"); // Not importing the builtin-path module was causing your build failure.
    const CopyWebpackPlugin = require("copy-webpack-plugin");
    const { DefinePlugin } = require("webpack");
    const cesiumSource = "node_modules/cesium/Source";
    const cesiumWorkers = "../Build/Cesium/Workers";
    module.exports = defineConfig({
      transpileDependencies: true,
      configureWebpack: {
        resolve: {
          fallback: { https: false, zlib: false, http: false, url: false },
        plugins: [
          new DefinePlugin({
            CESIUM_BASE_URL: JSON.stringify(""),
          new CopyWebpackPlugin({
            patterns: [
              { from: path.join(cesiumSource, "Assets"), to: "Assets" },
              { from: path.join(cesiumSource, "ThirdParty"), to: "ThirdParty" },
              { from: path.join(cesiumSource, "Widgets"), to: "Widgets" },
              { from: path.join(cesiumSource, cesiumWorkers), to: "Workers" },
    
  • Add a new CesiumViewer.vue component:
  • <script>
    import { Viewer } from "cesium";
    import "cesium/Source/Widgets/widgets.css";
    const viewer = new Viewer("app");
    viewer.scene.debugShowFramesPerSecond = true;
    </script>
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>
    #cesium-container {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    </style>
    
  • Edit your App.vue component to use the CesiumViewer.vue component:
  • <template>
      <div id="cesium-container">
        <CesiumViewer />
    </template>
    <script>
    import CesiumViewer from "./components/CesiumViewer.vue";
    export default {
      name: "App",
      components: {
        CesiumViewer,
    </script>
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    </style>
    

    Once you run npm run serve, everything should work:

    Hope this helps,

    Hi @sanjeetsuhag That was super helpful. The steps you outlined get the globe onscreen but I’m still having difficulty recreating my app. I’m trying to pull resources from Cesium ION but I’m having difficulty initializing the viewer (and yes…I have checked my token is valid :wink: ).

    <script>
    import Cesium from 'cesium/Source/Cesium';
    //import { Viewer } from "cesium";
    import "cesium/Source/Widgets/widgets.css";
    // Reference to access token
    Cesium.Ion.defaultAccessToken = '<TOKEN>';
    // Initialize the Cesium Viewer in the HTML element with the ID.
    const viewer = new Cesium.Viewer("app", {
      timeline: false,
      animation: false,
      baseLayerPicker: false,
      geocoder: false,
    const buildingsTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(-104.9965, 39.74248, 4000)
    //const viewer = new Viewer("app");
    viewer.scene.debugShowFramesPerSecond = true;
    </script>
    

    Currently I get the following error:

    Uncaught TypeError: Cannot read properties of undefined (reading 'Ion')
        at eval (CesiumViewer.vue?a500:7:1)
        at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:30:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue?vue&type=script&lang=js:5:215)
        at ./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:118:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue:2:99)
        at ./src/components/CesiumViewer.vue (app.js:96:1)
    

    I think the reference to ION in the error may be a red herring. If I remove the reference to Cesium.Ion.defaultAccessToken the error I get refers to the ‘Viewer’:

    app.js:220 Uncaught TypeError: Cannot read properties of undefined (reading 'Viewer')
        at eval (CesiumViewer.vue?a500:10:1)
        at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:30:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue?vue&type=script&lang=js:5:215)
        at ./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:118:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue:2:99)
        at ./src/components/CesiumViewer.vue (app.js:96:1)
    

    Is the reference import Cesium from 'cesium/Source/Cesium'; I added in the top of the script correct (derived from ES6 style import here: This tutorial explains how to integrate the Cesium npm module from webpack, and explores more advanced webpack configurations for optimizing an application using CesiumJS. – Cesium)? Do I need something additional in my vue.config.js?

    Many thanks!

    @virtualarchitectures The tutorial you referenced is outdated, unfortunately. You should import modules from the cesium package like this:

    import { Ion, Viewer } from "cesium";
                  

    Sorry @sanjeetsuhag but that doesn’t seem to be working. Is still get the error ‘Cesium is not defined’. VSCode is indicating that the import declarations are unused despite my referencing Cesium.Ion.defaultAccessToken= and const viewer = new Cesium.Viewer().

    Changing the above references to Ion.defaultAccessToken= and Viewer() by removing ‘Cesium’ allows the me to serve the app, but doesn’t load the resources from Cesium Ion and still gives the ‘Cesium not defined’ error.

    I can successfully import everything using import * as Cesium from "cesium"; instead. This works but I’d rather be importing just what’s needed for my build. I’ve poked about on GitHub but didn’t spot anything relevant. If there is any particular documentation or up-to-date examples you could point me to to help me understand the changes that would be much appreciated. It’s basically the boilerplate stuff that is giving me the headache I’m afraid.

    @virtualarchitectures When importing modules directly you don’t need to prefix them with the Cesuim.. For example,

    Cesium.Ion.defaultAccessToken = '0';
    

    should instead be:

    import { Ion } from "cesium"; Ion.defaultAccessToken = '0';

    but doesn’t load the resources from Cesium Ion and still gives the ‘Cesium not defined’ error.

    Can you describe what the error is? Are you using the Cesium. anywhere else in your app?

    In case it helps, here’s what the source code you posted above should look like:

    <script>
    import {
      Cartesian3,
      createOsmBuildings,
      Viewer
    } from "cesium";
    import "cesium/Source/Widgets/widgets.css";
    // Reference to access token
    Ion.defaultAccessToken = '<TOKEN>';
    // Initialize the Cesium Viewer in the HTML element with the ID.
    const viewer = new Viewer("app", {
      timeline: false,
      animation: false,
      baseLayerPicker: false,
      geocoder: false,
    const buildingsTileset = viewer.scene.primitives.add(createOsmBuildings());
    viewer.camera.flyTo({
      destination: Cartesian3.fromDegrees(-104.9965, 39.74248, 4000)
    viewer.scene.debugShowFramesPerSecond = true;
    </script>
                  

    Hi @sanjeetsuhag I realised that I was using the Cesium alias elsewhere where I had been calling Cesium3DTileSet(), IonResource.fromAssetId(), Cartesian3() and Math(). If I remove the preceding references I had to Cesium. and import each namespace or class separately the app serves successfully but still errors in the browser before loading my tileset or moving the camera.

    Probably better that I share some of my actual code rather than the boilderplate example to avoid confusion:

    <script>
    //import * as Cesium from "cesium";
    import { Ion, Viewer, IonResource, Cesium3DTileset, Cartesian3, Math } from "cesium";
    import "cesium/Source/Widgets/widgets.css";
    // Reference to access token
    Ion.defaultAccessToken = '<My Token>';
    // Initialize the Cesium Viewer in the HTML element with the "app" ID.
    const viewer = new Viewer("app", {
      timeline: false,
      animation: false,
      baseLayerPicker: false,
      geocoder: false,
    //------------------------3DTilesets------------------------//
    const tileset = <My Tileset>;
    const buildings = viewer.scene.primitives.add(
      new Cesium3DTileset({
        url: IonResource.fromAssetId(tileset),
    //------------------------Camera------------------------//
    tileset.readyPromise.then(function () {
      viewer.camera
        .flyTo({
          destination: Cartesian3.fromDegrees(-0.0970234, 51.3623602, 600),
          orientation: {
            heading: Math.toRadians(0.0),
            pitch: Math.toRadians(-20.0),
        .otherwise(function (error) {
          console.log(error);
    </script>
    

    The error in the broswer console refers to undefined properties:

    app.js:220 Uncaught TypeError: Cannot read properties of undefined (reading 'then')
        at eval (CesiumViewer.vue?a500:29:1)
        at ./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:30:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue?vue&type=script&lang=js:5:215)
        at ./src/components/CesiumViewer.vue?vue&type=script&lang=js (app.js:118:1)
        at __webpack_require__ (app.js:217:33)
        at fn (app.js:515:21)
        at eval (CesiumViewer.vue:2:99)
        at ./src/components/CesiumViewer.vue (app.js:96:1)
    

    That refers to webpack. In VSCode the terminal also provides the following warning in case it is relevant:

     warning  in ./src/components/CesiumViewer.vue?vue&type=script&lang=js
    export 'default' (reexported as 'default') was not found in '-!../../node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!../../node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./CesiumViewer.vue?vue&type=script&lang=js' (module has no exports)
    

    My feelings are there’s something wrong with my reference to Ion and/or there’s an issue with my vue.config.js which I assume is sent to webpack. The config file is currently an exact match for the one you’d provided above as is the App.vue so there should be no probs there.

    My package.json is as follows in case there are any version issue:

    "name": "vue_cesium_client", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build" "dependencies": { "cesium": "^1.99.0", "core-js": "^3.8.3", "vue": "^3.2.13" "devDependencies": { "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-service": "~5.0.0", "copy-webpack-plugin": "^11.0.0", "dotenv-webpack": "^8.0.1", "webpack": "^5.74.0"

    Apologies for making a meal of it but I’m very confused. If necessary I can go with the import all option. However, it would be really cool to see a Cesium guide or blogpost for Vuejs though.

    @virtualarchitectures From the code sample you posted above, it seems like the tileset variable is a number that contains the asset ID for the tileset hosted on Cesium ion. You’re then calling tileset.readyPromise.then which seems to be the source of the error. I believe that should be corrected to buildings.readyPromise.then since the buildings variable is the actual Cesium3DTileset.

    Should I ask another question about Cesium to run in Vue.js APP?
    In my case, I followed this demo code that it was success.
    But, when I import a KML file from this project of folder which always get an error message.

    Here is my code and my kml file.

    CesiumViewer.vue

    import * as Cesium from "cesium"
    import "cesium/Source/Widgets/widgets.css";
    const viewer = new Cesium.Viewer('app')
    viewer.scene.debugShowFramesPerSecond = true
    viewer.dataSources.add(Cesium.KmlDataSource.load('../SampleData/demo.kml',
            camera: viewer.scene.camera,
            canvas: viewer.scene.canvas
    

    package.json

    "name": "vue-cesium", "version": "0.1.0", "private": true, "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build", "lint": "vue-cli-service lint" "dependencies": { "cesium": "^1.100.0", "core-js": "^3.8.3", "vue": "^3.2.13" "devDependencies": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", "@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-service": "~5.0.0", "copy-webpack-plugin": "^9.1.0", "eslint": "^7.32.0", "eslint-plugin-vue": "^8.0.3", "webpack": "^5.75.0" "eslintConfig": { "root": true, "env": { "node": true "extends": [ "plugin:vue/vue3-essential", "eslint:recommended" "parserOptions": { "parser": "@babel/eslint-parser" "rules": {} "browserslist": [ "> 1%", "last 2 versions", "not dead", "not ie 11"

    Tree Commend

    KML File
    demo.kml (336.8 KB)

    Does Cesium is not support KmlDataSource to load KML file in vue framework?
    Or here are some mistake of setting in my project?

    Thank you for your anwser. :smile_cat:

    You’ll need to ensure your asset files are getting served. Static asset files, like KML, aren’t bundled into your JavaScript, so you’ll need to handle them seperately.

    Usually, you can use the copy-webpack-plugin to copy them over to your build directory and serve them in your app.

    Hi, I have followed the guide and now I’m getting those errors:

    ERROR in node:url
    Module build failed: UnhandledSchemeError: Reading from “node:url” is not handled by plugins (Unhandled scheme).
    Webpack supports “data:” and “file:” URIs by default.
    You may need an additional plugin to handle “node:” URIs.