【WebGIS系列】Typescript+WebGL+Webpack开发环境搭建 (2)

但这并不是最终的解决方案,因为如果使用ts-loader作为Webpack集成的话,Webpack并不能获取tsconfig.json的别名配置,也就是说,Webpack将会抛出not found错误。awesome-typescript-loader很好地解决了这个问题,它可以将tsconfig.json的别名配置映射至Webpack的resolve.alias。当然,如果你仍然坚持使用ts-loader也可以解决,如果你不怕麻烦的话:在Webpack中手动配置同样的resolve.alias。

另外需要注意的是,使用awesome-typescript-loader需要在Webpack的resolve中创建对应的插件:

const TsConfigPathsPlugin = require('awesome-typescript-loader').TsConfigPathsPlugin; module.exports = { module: { rules: [{ test: /\.ts$/, exclude: /node_modules/, use: ['babel-loader','awesome-typescript-loader'] }, // other rules ] }, resolve: { plugins: [ new TsConfigPathsPlugin({ configFileName: Path.resolve(__dirname,'../tsconfig.json') }) ] } } shader

WebGL创建shader的流程为:

首先创建指定类型的shader实例;

将shader源码与实例绑定;

编译shader。

示例代码如下:

const source = ` precision mediump float; attribute vec2 a_pos; uniform vec4 u_color; uniform vec2 u_resolution; uniform vec2 u_translate; varying vec4 v_color; void main() { vec2 real_poistion = (a_pos+u_translate) / u_resolution * 2.0 - 1.0; gl_Position = vec4(real_poistion * vec2(1, 1), 0, 1); v_color = u_color; }`; // 创建shader实例 const Shader = gl.createShader(gl.VERTEX_SHADER); // 绑定shader源码 gl.shaderSource(Shader,source); // 编译 gl.compileShader(Shader);

shader的源码以字符串的形式绑定至shader实例,也就是说,不论shader的源码是用什么编程语言编写(比如可以按照上述代码中用JavaScript字符串编写,也可以直接用glsl语言编写),一定要保证以字符串的形式引入shader源码模块。秉承这项原则,最简单的shader构建方案便是上述代码中的字符串形式。比如将上述示例代码中的shader源码单独抽离为vertex.js如下:

export default ` precision mediump float; attribute vec2 a_pos; uniform vec4 u_color; uniform vec2 u_resolution; uniform vec2 u_translate; varying vec4 v_color; void main() { vec2 real_poistion = (a_pos+u_translate) / u_resolution * 2.0 - 1.0; gl_Position = vec4(real_poistion * vec2(1, 1), 0, 1); v_color = u_color; }`;

然后在主文件中引入:

import VertexShaderSource from './vertex.js'; // 创建shader实例 const Shader = gl.createShader(gl.VERTEX_SHADER); // 绑定shader源码 gl.shaderSource(Shader,VertexShaderSource); // 编译 gl.compileShader(Shader);

这种书写方式优点是不需要对Webpack进行任何配置,但是却等于放弃了IDE对glsl语法的高亮、纠错等辅助功能。如果shader源码只有几行倒也没什么大问题,但是对于几十上百行的代码如果没有高亮辅助的话可能会严重影响开发效率。

解决这个问题的办法要从两方面入手:

令Webpack能够正确编译glsl代码;

令TypeScript能够将glsl模块与ts模块融合。

第一个问题很好解决,因为我们的目的是把glsl模块引入到js模块中并且作为字符串使用,所以Webpack要做的就是将glsl源码构建为字符串即可:

{ test: /\.glsl$/, loader: 'raw-loader' }

raw-loader的功能是将被引入的文件内容转换为字符串。

除了强类型带来的开发模式转变以外,TypeScript最大的问题是不能自动识别ts以外的任何其他类型模块,即使最普遍的JSON也不行。比如下述代码在TypeScript环境下会报not found错误:

import Data from '../data.json';

这时候需要用到TypeScript的声明文件。声明文件的作用简单来说就是告知TypeScript编译器一些必要的信息以便被正确识别。比如声明一些全局的类型(type)、接口(interface)、模块(module)等。

默认情况下,TypeScript编译器会自动识别源码和node_modules目录中@types文件夹内的声明文件,你也可以通过配置tsconfig.json中compilerOptions.typeRoots指定声明文件目录。针对上文提到的TypeScript不识别glsl和json模块问题,我们在源码目录的@types文件夹中创建声明文件global.d.ts,内容如下:

declare module '*.glsl'; declare module '*.json'; declare type WidthAndHeight = { width: number; height: number; };

上述代码中声明了三个信息:

声明glsl后缀类型的文件为可识别模块;

声明json后缀类型的文件为可识别模块;

声明全局类型WidthAndHeight,此类型将在任何源码文件中直接使用。

在以上配置的基础上还有一个注意事项:与ES6 modules不同的是,TypeScript引入declare声明的非ts模块并不能将其内容自动转化为默认导出,即export default。比如在ES6环境下引入一个json文件:

import JsonData from './data.json';

而在TypeScript环境下需要使用以下语法:

import * as JsonData from './data.json'; 示例代码

具体代码可以参考demo:https://github.com/ihardcoder/demo_ts-webgl-webpack

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzdzs.html