这一次我们谈谈模块问题。

通常我们希望这个项目可以分为多个独立的模块,比如,上一次提高的 hello 函数,如果我们定义为一个模块,其它模块引用之后,直接调用就好了。在前端怎么使用模块呢?这可说来话长了。

如果我们把 hello 函数定义在文件 hello.js 中,内容如下:

  1. function hello(){
  2. alert("Hello, Webpack!");
  3. }

然后把主入口函数 index.js 的内容写成下面的内容,你应该会得到一个错误信息。

  1. require("./hello");
  2.  
  3. hello();

对话框是弹不出来的。错误信息如下:

Uncaught ReferenceError: hello is not defined, 明明定义了 hello 函数,却偏偏说找不到。

1. CommonJs 模块

CommonJs 是目前比较流行,也是出现较早的模块技术,它诞生于 NodeJs,使用起来其实比较简单。

首先,它把一个独立的文件看成一个模块,比如上面的 hello.js 文件,就可以当成一个模块。模块的名称就是文件名称,但是可以不用提供扩展名 .js,直接使用文件名就可以。

在导入一个模块的时候,使用 require 函数,注意是函数,并不是关键字,JavaScript 并没有提供这个关键字。函数的参数就是模块名称,不过,要注意模块分为两种,自定义的模块和系统模块。

自定义的模块必须使用 . 或者 .. 开头的相对路径,如果都在同一个目录下,也需要使用 . 来表示当前路径,比如上面用到的 require("./hello")。

不是使用 . 或者 .. 开始的相对路径的,都称为系统模块,系统模块的路径其实在 node_modules 文件夹中,每个子文件夹就是一个系统模块。

require 函数的返回结果就是模块导出的内容。

我们的模块没有导出任何内容。所以,虽然被 index 引用了,但是在 index 中却是无法访问的。这也说明模块中定义的函数其实是局部函数,并不是通常意义上的全局函数了。

我们要在模块中导出内容怎么办呢,CommonJs 提供了 exports 对象。

在 CommonJs 模块中,希望导出的内容必须通过 exports 对象,这是 CommonJs 系统提供的系统对象,我们可以直接使用。导出的内容以键值对的形式定义到这个对象上,键就是导出的名称,值就是准备导出的内容。

比如,我们希望将 hello 函数导出为名为函数的函数,好像挺绕的,其实很简单。

  1. function hello(){
  2. alert("Hello, Webpack!");
  3. }
  4.  
  5. exports.hello = hello;

将 index.js 函数的定义修改为

  1. var hello = require("./hello").hello;
  2.  
  3. hello();

重新执行 webpack 命令,刷新网页,你会看到函数执行了。

2. AMD 模块

另外一个著名的模块系统称为 AMD 模块,全称为 Asynchromous Module Defination,翻译过来就是异步模块规范,它是由 RequireJs 推动的。

首先,一个文件也被看作一个模块,所以,我们还拿 hello.js 作为一个模块吧。

其次,定义模块使用 define 函数,函数的第一个参数是当前模块依赖的模块数组,如果没有依赖的函数,可以使用一个空的数组表示。

  1. define([], function(){
  2. return {
  3. hello: function(){
  4. alert("Hello, Webpack!");
  5. }
  6. };
  7. });

第二个参数就是模块的定义函数,这个函数的返回内容就是模块的导出内容。我们这里导出一个对象包含我们定义的函数的对象。

最后,我们修改一下 index.js 来导入定义好的 AMD 模块,并调用 hello 函数。

  1. define(['./hello'], function( helloModule ){
  2. helloModule.hello();
  3. })

这次,我们的 index 依赖提前定义好的 hello 模块,注意模块命名的方式还是注意自定义模块和系统模块的区别,在第二个函数参数中,它的参数就是被依赖模块导出的内容,所以这里的 helloModule 就是一个对象,它的 hello 属性就是我们定义好的函数。

3. ES 2015 和 TypeScript 中的模块

在 ES2015 中,定义了关键字,注意是关键字,不是函数了,模块导出的关键字是 export , 导入就是 import 了。

所以,hello 函数可以这样定义了。

  1. export default function() {
  2. alert("Hello, Webpack!");
  3. };

而 index.js 就可以这样定义。

  1. import hello from "./hello";
  2.  
  3. hello();

但是,需要注意的是,你必须有 ES2015 的运行环境才行,目前很多浏览器不支持怎么办呢?

我们可以将 ES2015 的代码先翻译成标准的 JavaScript 代码,就可以执行了。

而 TypeScript 作为 ES2015 的超集,我们就使用 TypeScript 来实现。

首先,你必须确认你已经安装了 TypeScript 的编译器,全局安装 TypeScript

  1. npm -g install typescript

安装之后,可以执行 tsc -v 来检查版本,目前最新是 2.0.3 版本。

将 hello.js 重新改名为 hello.ts,将 index.js 改名为 index.ts. ts 是 TypeScript 文件的扩展名。

你可以手工执行命令 tsc 分别将两个 typescript 文件编译为 javascript 文件。

生成的 hello.js

  1. "use strict";
  2. function default_1() {
  3. alert("Hello, Webpack!");
  4. }
  5. exports.__esModule = true;
  6. exports["default"] = default_1;
  7. ;

生成的 index.js

  1. "use strict";
  2. var hello_1 = require("./hello");
  3. hello_1["default"]();

然后,再次执行 webpack 重新打包,你会发现结果仍然正常执行。

4. 使用 tsloader

在第三步,我们可以手工使用 tsc 将 TypeScript 代码编译为 JavaScript 代码之后进行打包,但是这样太麻烦了,使用 ts-loader 我们可以让 webpack 自动先调用 tsc 将 TypeScript 代码编译为 JavaScript 代码,然后再自动进行打包工作。

首先,当然要安装 ts-loader 插件了。

  1. npm install ts-loader --save-dev

目前是 0.9.5 版本。

为了在项目中使用 typescript,你还需要本地安装 typescript 一次。

  1. npm install typescript --save-dev

还需要配置一下 TypeScript 如何编译代码。在当前目录中创建名为 tsconfig.json 的配置文件。

  1. {
  2. "compilerOptions": {
  3. "target": "es5",
  4. "sourceMap": true
  5. },
  6. "exclude": [
  7. "node_modules"
  8. ]
  9. }

这里的配置是说,希望生成 es5 标准的 JavaScript 目标文件。

然后,配置 webpack 使用 ts-loader

  1. var HtmlwebpackPlugin = require('html-webpack-plugin');
  2.  
  3. module.exports = {
  4. // 入口
  5. entry: "./index.ts",
  6. // 输出的文件名
  7. output: {
  8. filename: 'bundle.js'
  9. },
  10. resolve: {
  11. // Add `.ts` and `.tsx` as a resolvable extension.
  12. extensions: ['', '.ts', '.js']
  13. },
  14. // 添加我们的插件 会自动生成一个html文件
  15. plugins: [
  16. new HtmlwebpackPlugin({
  17. title: 'Hello Webpack'
  18. })
  19. ],
  20. module: {
  21. loaders: [
  22. // all files with a `.ts` extension will be handled by `ts-loader`
  23. { test: /\.ts$/, loader: 'ts-loader' }
  24. ]
  25. }
  26. };

这里增加了两个内容,一个是 resolve 配置,这样我们只需要使用模块名称,webpack 会自动添加后缀来查找模块文件。另一个就是 module 中的 loader 了,这里是说遇到了 .ts 扩展名的文件,需要先使用 ts-loader 处理之后再打包。

现在,重新执行 webpack 命令,你会发现一切都已经处理好了,刷新页面,你应该看到代码正确执行了。

5. 总结

webpack 可以直接支持 CommonJs 和 AMD 模块,对于 TypeScript ,我们还需要安装 TypeScript 和 ts-loader.

需要注意的是 Angular 2 使用 TypeScript 作为主力语言,你能做到这里,离 Angular 2 已经很近了。

Webpack 入门指南 - 3. Hello, Angular2!

Webpack 入门指南 - 2.模块的更多相关文章

  1. Webpack 入门指南 - 3. Hello, Angular2!

    Webpack 入门指南 - 1.安装 Webpack 入门指南 - 2.模块 这一次,我们使用 Webpack 来打包 Angular 2 的应用. 与官方的 Hello, Angular 2 项目 ...

  2. Webpack 入门指南 - 1.安装

    Webpack 是目前流行的打包工具,如何安装它呢? 1. 安装 Node Js 首先,Webpack 是基于 NodeJs 的工具,你必须首先安装 NodeJs. NodeJs 仅仅只需要在你的系统 ...

  3. 一小时包教会 —— webpack 入门指南

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  4. 【一小时入门】webpack 入门指南

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  5. webpack入门指南-step03

    一.webpack 的使用 webpack简单点来说就就是一个配置文件,所有的魔力都是在这一个文件中发生的. 这个配置文件主要分为三大块 entry 入口文件 让webpack用哪个文件作为项目的入口 ...

  6. webpack入门指南(基于webpack v4.41.2)

    2019年12月5日初稿,目前webpack已经更新到v4.41.2,本文正是基于该版本,在windows8.1操作系统下进行的demo编译,适用于想入门webpack的前端开发人员. webpack ...

  7. webpack入门指南(转载)

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  8. webpack 入门指南

    很久没有更博了... 这就把最近积累用到的知识点更新到这里.. 望 共勉 什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffe ...

  9. webpack入门指南-step04

    一.建立项目 建一个文件夹,然后新建一个package.json的文件在项目根目录下 如果你使用git管理你的这个项目的话,建议你新建一个.gitignore文件,不要让git提交一些node依赖的模 ...

随机推荐

  1. STM3210x建工程库函数版本

    1.首先下载一个固件库,我下载的是stm32f10x_stdperiph_lib 3.5V版的 2.新建一个文件夹,可命名为"STM32建工程库函数版本" 3.在"STM ...

  2. e

    frame问题 以下面的frame为例: ? 1 <frame  src=”xxx.html”  id=”frameId”  name=”frameName”  /> (1)访问frame ...

  3. 新建STM32工程

    1) 2)保存 3)选择公司和芯片的型号,STM32F103C8T6,64kB Flash, 20kB SRAM. 4)手动添加启动代码 5)新建如下文件夹 6)回到工程,选中target,右键Add ...

  4. Ionic2学习笔记

    Component nav: <ion-nav [root] = 'rootComponent'></ion-nav> ....import {Nav} from 'ionic ...

  5. js本地图片预览

    相信大家都遇到过上传图片之前预览,网上找了很多,但都不是所有浏览器都支持,不过后来找到一个,但自己没有完全实验. 代码如下: <script> //使用IE条件注释来判断是否IE6,通过判 ...

  6. 【python】pandas & matplotlib 数据处理 绘制曲面图

    Python matplotlib模块,是扩展的MATLAB的一个绘图工具库,它可以绘制各种图形 建议安装 Anaconda后使用 ,集成了很多第三库,基本满足大家的需求,下载地址,对应选择pytho ...

  7. AJAX 状态值(readyState)与状态码(status)详解

    总结:status体现的是服务器对请求的反馈,而readystate表明客户端与客户的交互状态过程. 1- AJAX状态值与状态码区别AJAX状态值是指,运行AJAX所经历过的几种状态,无论访问是否成 ...

  8. 《Matrix Computation 3rd》读书笔记——第3章 一般线性系统

  9. JSBinding+Bridge.NET:生成绑定(导出)

    将框架代码导出到 JavaScript.就可以在 JavaScript 中调用 框架代码 的功能. 注意,这个功能是在 Js工程中做的,Cs工程没有这回事. 如何导出? 1. 将需要导出的类添加到 J ...

  10. kali-dmitry 域名信息收集

    DMirty:用来收集以下信息: 1. 端口扫描 2. whois主机IP和域名信息 3. 从Netcraft.com获取主机信息 4. 子域名 5. 域名中包含的邮件地址 1.使用方法: Deepm ...