Vue + TypeScript 简单项目 + RequireJs

安装 Vue-cli 和 TypeScript

  1. 安装 typescript $npm install -g typescript
  2. 安装 Vue 命令行工具: $npm install -g vue-cli ,安装完成之后对应的命令行工具为 vue 可以通过 vue --help 来获得使用帮助。
  3. 我们通过 vue init 命令来初始化一个简单的项目。
    vue init simple VueToDoDemo1 其中的 simple 表示项目模块名称。其他自带的模板可以通过 vue list 查看。按创建提示初始化好之后,进入项目目录。
    可以发现vue 只是为我们创建了一个简单的 index.html 文件。

简易集成 TypeScript

  1. 使用 $npm init 加入 npm 支持。
  2. 使用 npm 安装 vue$npm install vue
  3. 使用 tsc 创建项目需要的 tsconfig.json 文件。 $tsc --init
  4. vue-cli 生成的 vue代码使用 TypeScript 重写。
    首先,创建一个 app.ts 文件,如下:
    由于 TS 是 JS 的超集,所以我只是简单的复制了原有的 <script> 标签中的代码,
 var app = new Vue({
      el: '#app',
      data: {
        greeting: 'Welcome to your Vue.js app!',
        docsURL: 'http://vuejs.org/guide/',
        discordURL: 'https://chat.vuejs.org',
        forumURL: 'http://forum.vuejs.org/'
      },
      methods: {
        humanizeURL: function (url) {
          return url
            .replace(/^https?:\/\//, '')
            .replace(/\/$/, '')
        }
      }
    })
  1. 使用 tsc 编译 直接在项目根目录运行 tsc 然后 app.ts 会编译成 app.js
    当然因为我们本身就是 JS 代码,所以没什么变化 。

  2. 将原来 index.html 中的 script元素使用。使用 <script src="app.js"> </script> 替换。

打包与模块

在上面的步骤中,会提示这样的错误:

app.ts(1,16): error TS2304: Cannot find name 'Vue'.

首先,我们使用 将 tsconfig.json 中的 "moduleResolution":"node" 配置取消注释。
然后在 app.ts 开头添加如下导入声明:
import Vue from "vue" 然后再运行 tsc 就没有这个错误了。

修改之后,再次刷新 chrome 提示错误:

Uncaught SyntaxError: Unexpected identifier


image.png

搜索了一下,建议给 script 标签加上 type="module" 属性。
修改之后提示跨域错误:

Access to Script at 'file:///Users/banxi/Workspace/VueToDoDemo1/app.js' from origin 'null' has been blocked by CORS policy: Invalid response. Origin 'null' is therefore not allowed access.

那我们不使用 file 协议来运行 index.html 文件。而是使用一个简单的 http 服务器,以避免上面的 CORS 问题。
可以使用 Python 来在当前目录当作 Web 的根目录。
python -m SimpleHTTPServer 8000 然后使用 http://localhost:8000/index.html 来访问。

同时将 index.html 头部的 vue 引用改成如下:
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.esm.js" type="module"></script> 指定为引用 ES Module 兼容的版本。

但是还是报如下的错误:

vue.esm.js:370 Uncaught ReferenceError: process is not defined
at vue.esm.js:370

原因是 Vue 代码包含了对 Node 环境原始的 process.env.NODE_ENV 检查。所以还存在 Node 的process 对象引用。
从文档: https://cn.vuejs.org/v2/guide/installation.html 中是建议的话 esm 版本本来就是用来提供给 webpack 等打包工具用的。如果直接用 vue.js 版本的话则会提示如下的错误:

vue.js:9 Uncaught TypeError: Cannot set property 'Vue' of undefined
at vue.js:9
at vue.js:10

然后考虑到上面文档说,cdn的 Vue 就是‘UMD版本, 于是’改用UMD包。编译出的app.js` 如下:

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "vue"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var vue_1 = __importDefault(require("vue"));
    var app = new vue_1.default({
        el: '#app',
        data: {
            greeting: 'Welcome to your Vue.js app!',
            docsURL: 'http://vuejs.org/guide/',
            discordURL: 'https://chat.vuejs.org',
            forumURL: 'http://forum.vuejs.org/'
        },
        methods: {
            humanizeURL: function (url) {
                return url
                    .replace(/^https?:\/\//, '')
                    .replace(/\/$/, '');
            }
        }
    });
});

这样报错是没有报错了,但是感觉中间的代码没有执行。

然后尝试采用 amd 打包方式。编译后的代码如下:

var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
define(["require", "exports", "vue"], function (require, exports, vue_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    vue_1 = __importDefault(vue_1);
    var app = new vue_1.default({
        el: '#app',
        data: {
            greeting: 'Welcome to your Vue.js app!',
            docsURL: 'http://vuejs.org/guide/',
            discordURL: 'https://chat.vuejs.org',
            forumURL: 'http://forum.vuejs.org/'
        },
        methods: {
            humanizeURL: function (url) {
                return url
                    .replace(/^https?:\/\//, '')
                    .replace(/\/$/, '');
            }
        }
    });
});

可以看到其实 UMD 的打包方式。其实通过了自己的方式来兼容了 amd 的打包方式。
于是在 index.html 头部先引入 require.js
<script src="https://cdn.bootcss.com/require.js/2.3.5/require.js"></script>
然后没有报错了。但是还是觉得代码没有执行的感觉。
然后继续按 require.js 的模块定义及加载方式。来使用。

 <script src="https://cdn.bootcss.com/require.js/2.3.5/require.js"></script>
  <script>
    require.config({
        paths:{
            "vue": "https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue"
        }
    })
    require(["vue","app"],function(vue,app){
        console.log("module loaded");
    });
  </script>

这里面说明了 require.js 使用上的两个特点。
1)CDN 资源可以通过 require.config 配置后使用。注意配置时路径后面的 .js 不要写,因为会自动加上。
2)本地 JS 模块可以直接通过模块名称(即文件名称)

到此现在 TypeScript + RequireJs 打包结合,已经将此 Demo 初步完善了。
后面将增加 Vue Component 及其他加入 Webpack 打包的集成。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 慕课网@JoJozhai 老师 TypeScript入门课程分享 TypeScript入门 ES5,ES6,JS,...
    shangpudxd阅读 13,558评论 0 22
  • Leonard E. Read 今天我来给你解释,人们的生活变得越来越美好的原因,你一定能够从这只神奇的铅笔当中找...
    孤独中的喧嚣阅读 4,922评论 0 2
  • 要论上热搜谁最强,郑爽无人能敌,不管是什么影视剧,只要有郑爽似乎都成了收视保证,意外的是,她主演的古装剧《美人私房...
    辣八阅读 1,950评论 0 0
  • 叮铃铃上课铃响了,上午的语文课就要开始啦!老师先给我们唱对韵歌。我给大家唱一遍《对韵歌》,云对雨,雪对风。花对树,...
    45cbff51831c阅读 1,805评论 0 2
  • 青春散场之后,没说再见的人,以后再也见不到了。 阳光很是舒服,懒散的生活终于快要走到了头。曾以为不顾一切的去远方,...
    一只叫帕丁顿的熊阅读 2,454评论 0 1

友情链接更多精彩内容