使用typescript+webpack构建一个js库的示例详解

目录
  • 入口文件
  • tsconfig配置
  • webpack配置文件
    • webpack入口文件配置
    • webpack为typescript和less文件配置各自的loader
    • webpack的output配置
    • 运行webpack进行打包
    • 测试验证
  • 输出esm模块
    • 已经输出了umd格式的js了, 为什么还要输出esm模块? ----TreeShaking
    • 用tsc输出esm和类型声明文件
      • package.json中添加exports配置声明模块导出路径
  • 完善package.json文件
  • 用api-extractor提取出干净的.d.ts
    • 配置使用API extractor
    • 更新package.json
    • 用@internal标注只希望在内部使用的class
  • 小结

记录使用typescript配合webpack打包一个javascript library的配置过程.

目标是构建一个可以同时支持CommonJs, esm, amd这个几个js模块系统的javascript库, 然后还有一个单独打包出一个css的样式文件的需求.

为此以构建一个名为loaf的javascript库为例; 首先新建项目文件目录loaf, 并进入此文件目录执行npm init命令, 然后按照控制台的提示输入对应的信息, 完成后就会在loaf目录下得到一个package.json文件

然后使用npm i命令安装所需的依赖

npm i -D webpack webpack-cli typescript babel-loader @babel/core @babel/preset-env @babel/preset-typescript ts-node @types/node @types/webpack mini-css-extract-plugin css-minimizer-webpack-plugin less less-loader terser-webpack-plugin

依赖说明

  • webpack webpack-cli: webpack打包工具和webpack命令行接口
  • typescript: 用于支持typescript语言
  • babel-loader @babel/core @babel/preset-env @babel/preset-typescript: babel相关的东西, 主要是需要babel-loader将编写的typescript代码转译成es5或es6已获得更好的浏览器兼容性
  • ts-node @types/node @types/webpack: 安装这几个包是为了能用typescript编写webpack配置文件(webpack.config.ts)
  • mini-css-extract-plugin less less-loader: 编译提取less文件到单独的css文件的相关依赖
  • css-minimizer-webpack-plugin terser-webpack-plugin: 用于最小化js和css文件尺寸的webpack插件

入口文件

通常使用index.ts作为入口, 并将其放到src目录下, 由于有输出样式文件的需求, 所以还要新建styles/index.less

mkdir src && touch src/index.ts
mkdir src/styles && touch src/styles/index.less

tsconfig配置

新建tsconfig.json文件

touch tsconfig.json

填入以下配置(部分选项配有注释):

{
    "compilerOptions": {
        "outDir": "dist/lib",
        "sourceMap": false,
        "noImplicitAny": true,
        "module": "commonjs",
        // 开启这个选项, 可以让你直接通过`import`的方式来引用commonjs模块
        // 这样你的代码库中就可以统一的使用import导入依赖了, 而不需要另外再使用require导入commonjs模块
        "esModuleInterop": true,
        // 是否允许合成默认导入
        // 开启后, 依赖的模块如果没有导出默认的模块
        // 那么typescript会帮你给该模块自动合成一个默认导出让你可以通过默认导入的方式引用该模块
        "allowSyntheticDefaultImports": true,
        // 是否生成`.d.ts`的类型声明文件
        "declaration": true,
        // 输出的目标js版本, 这里用es6, 然后配和babel进行转译才以获得良好的浏览器兼容
        "target": "es6",
        "allowJs": true,
        "moduleResolution": "node",
        "lib": ["es2015", "dom"],
        "declarationMap": true,
        // 启用严格的null检查
        "strictNullChecks": true,
        // 启用严格的属性初始化检查
        // 启用后类属性必须显示标注为可空或赋一个非空的初始值
        "strictPropertyInitialization": true
    },
    "exclude": ["node_modules"],
    "include": ["src/**/*"]
}

webpack配置文件

创建webpack.config.ts

touch webpack.config.ts

webpack.config.ts

import path from "path";
import { Configuration, Entry } from "webpack";
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import CssMinimizer from 'css-minimizer-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin'
const isProd = process.env.NODE_ENV === 'production';

/**
 * 这里用到了webpack的[Multiple file types per entry](https://webpack.js.org/guides/entry-advanced/)特性
 * 注意`.less`入口文件必须放在`.ts`文件前 */
const entryFiles: string[] = ['./src/styles/index.less', './src/index.ts'];
const entry: Entry = {
  index: entryFiles,
  'index.min': entryFiles,
}; 

const config: Configuration = {
  entry,
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({ test: /.min.js$/ }),
      new CssMinimizer({
        test: /.min.css$/,
      }),
    ],
  },
  module: {
    rules: [
      {
        test: /.ts$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          presets: ['@babel/env', '@babel/typescript'],
        },
      },
      {
        test: /.less$/,
        use: [
          isProd ? MiniCssExtractPlugin.loader : 'style-loader',
          {
            loader: 'css-loader',
          },
          'postcss-loader',
          'less-loader',
        ],
      },
    ],
  },
  output: {
    path: path.resolve(__dirname, 'dist/umd'),
    library: {
      type: 'umd',
      name: {
        amd: 'loaf',
        commonjs: 'loaf',
        root: 'loaf',
      },
    },
  },
  resolve: {
    extensions: ['.ts', '.less'],
  },
  devtool: 'source-map',
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
};
export default config;

webpack入口文件配置

...
const isProd = process.env.NODE_ENV === 'production';

/**
 * 这里用到了webpack的[Multiple file types per entry](https://webpack.js.org/guides/entry-advanced/)特性
 * 注意`.less`入口文件必须放在`.ts`文件前 */
const entryFiles: string[] = ['./src/styles/index.less', './src/index.ts'];
const entry: Entry = {
  index: entryFiles,
  'index.min': entryFiles,
}; 

const config: Configuration = {
  entry,
  ...
}
...

在上面的webpack.config.json中,我们配置了两个入口分别是indexindex.min,不难看出,多出的一个index.min入口是为了经过压缩后js和css文件,在生产环境使用一般都会使用.min.js结尾的文件以减少网络传输时的尺寸; 实现这个还需要结合optimization相关配置, 如下:

optimization: {
   minimize: true,
   minimizer: [
     new TerserPlugin({ test: /.min.js$/ }),
     new CssMinimizer({
       test: /.min.css$/,
     }),
   ],
 },

另外,indexindex.min的值都是相同的entryFiles对象,这个对象是一个字符串数组,里面放的就是我们的入口文件相对路径,这里一定要注意把./src/styles/index.less置于./src/index.ts之前。

webpack为typescript和less文件配置各自的loader

配置完入口后, 就需要为typescript和less代码配置各自的loader

module: {
    rules: [
      {
        test: /.ts$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          presets: ['@babel/env', '@babel/typescript'],
        },
      },
      {
        test: /.less$/,
        use: [
          isProd ? MiniCssExtractPlugin.loader : 'style-loader',
          {
            loader: 'css-loader',
          },
          'postcss-loader',
          'less-loader',
        ],
      },
    ],
},
  • mini-css-extract-plugin less less-loader: 编译提取less文件到单独的css文件的相关依赖

上面的配置为.ts结尾的文件配置了babel-loader; 为.less结尾的文件配置一串loader, 使用了use, use中的loader的执行顺序是从后往前的, 上面less的配置就是告诉webpack遇到less文件时, 一次用less-loader->postcss-loader->css-loader->生产环境用 MiniCssExtractPlugin.loader() 否则用 style-loader;

MiniCssExtractPlugin.loader使用前要先在plugins进行初始化

...
const config = {
...
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
  ],
...
}
...

webpack的output配置

...
const config = {
...
  output: {
    path: path.resolve(__dirname, 'dist/umd'),
    library: {
      type: 'umd',
      name: {
        amd: 'loaf',
        commonjs: 'loaf',
        root: 'loaf',
      },
    },
  },
...
}
...

这里配置webpack以umd的方式输出到相对目录dist/umd目录中, umdUniversal Module Definition(通用模块定义)的缩写, umd格式输出library允许用户通过commonjs, AMD, <script src="...">的方式对library进行引用config.library.name可以为不同的模块系统配置不同的导出模块名供客户端来进行引用; 由于这里的导出模块名都是loaf, 所以也可以直接config.library.name设置成loaf.

运行webpack进行打包

现在回到最开始通过npm init生成的package.json文件, 在修改其内容如下

{
  "name": "loaf",
  "version": "1.0.0",
  "description": "A demo shows how to create & build a javascript library with webpack & typescript",
  "main": "index.js",
  "scripts": {
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "test": "npm run test"
  },
  "keywords": [
    "demo"
  ],
  "author": "laggage",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@types/node": "^18.0.0",
    "@types/webpack": "^5.28.0",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss-loader": "^7.0.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "ts-node": "^10.8.2",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

新增了一个脚本命令 "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production", 然后命令行到项目目录下执行npm run build:umd, 不出意外应该就构建成功了, 此时生成的dist目录结构如下

dist
└── umd
    ├── index.css
    ├── index.js
    ├── index.js.map
    ├── index.min.css
    ├── index.min.js
    └── index.min.js.map

1 directory, 6 files

测试验证

新建demo.html进行测试

mkdir demo && touch demo/demo.html

demo/demo.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="../dist/umd/index.js"></script>
    <script type="text/javascript">
        console.log(loaf, '\n', loaf.Foo)
    </script>
</body>
</html>

用浏览器打开demo.html, 然后F12打开控制台, 可以看到如下输出则说明初步达成了目标:

Module {__esModule: true, Symbol(Symbol.toStringTag): 'Module'}
demo.html:13 ƒ Foo() {
    var _bar = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Bar();

    src_classCallCheck(this, Foo);

    this._bar = _bar;
  }

输出esm模块

完成上面的步骤后, 我们已经到了一个umd模块的输出, 相关文件都在dist/umd目录下; 其中包含可供CommonJs ESM AMD模块系统和script标签使用的umd格式的javascript文件和一个单独的css样式文件.

已经输出了umd格式的js了, 为什么还要输出esm模块? ----TreeShaking

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export. The name and concept have been popularized by the ES2015 module bundler rollup.

此库的使用者也使用了类似webpack之类的支持Tree Shaking
的模块打包工具,需要让使用者的打包工具能对这个js库loaf进行死代码优化Tree Shaking

从webpack文档中看出, tree-shaking依赖于ES2015(ES2015 module syntax, ES2015=ES6)的模块系统, tree-shaking可以对打包体积有不错优化, 所以为了支持使用者进行tree-shaking, 输出esm模块(esm模块就是指 ES2015 module syntax)是很有必要的.

用tsc输出esm和类型声明文件

tsc -p tsconfig.json --declarationDir ./dist/typings -m es6 --outDir dist/lib-esm

上面的命令使用typescript编译器命令行接口tsc输出了ES6模块格式的javascript文件到dist/lib-esm目录下

将这个目录加入到package.jsonscripts配置中:

package.json

{
  "name": "loaf",
  "version": "1.0.0",
  "description": "A demo shows how to create & build a javascript library with webpack & typescript",
  "main": "index.js",
  "scripts": {
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "build:lib-esm": "tsc -p tsconfig.json --declarationDir ./dist/typings -m es6 --outDir dist/lib-esm",
    "test": "npm run test"
  },
  "keywords": [
    "demo"
  ],
  "author": "laggage",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@types/node": "^18.0.0",
    "@types/webpack": "^5.28.0",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss-loader": "^7.0.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "ts-node": "^10.8.2",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

然后运行: npm run build:lib-esm, 此时dist目录结构如下:

dist
├── lib-esm
│   ├── bar.js
│   └── index.js
├── typings
│   ├── bar.d.ts
│   ├── bar.d.ts.map
│   ├── index.d.ts
│   └── index.d.ts.map
└── umd
    ├── index.css
    ├── index.js
    ├── index.js.map
    ├── index.min.css
    ├── index.min.js
    └── index.min.js.map

3 directories, 12 files

多出了两个子目录分别为lib-esmtypings, 分别放着es6模块格式的javascript输出文件和typescript类型声明文件.

完善package.json文件

到目前为止, package.json的scripts配置中, 已经有了build:umdbuild:lib-esm用于构建umd格式的输出和esm格式的输出, 现在我们再向添加一个build用来组合build:umdbuild:lib-esm并进行最终的构建, 再次之前先安装一个依赖shx, 用于跨平台执行一些shell脚本: npm i -D shx;

更新package.json文件:

package.json

{
  "name": "loaf",
  "version": "1.0.0",
  "description": "A demo shows how to create & build a javascript library with webpack & typescript",
  "main": "index.js",
  "scripts": {
    "build": "shx rm -rf dist/** && npm run build:umd && npm run build:lib-esm",
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "build:lib-esm": "tsc -p tsconfig.json --declarationDir ./dist/typings -m es6 --outDir dist/lib-esm",
    "test": "npm run test"
  },
  "keywords": [
    "demo"
  ],
  "author": "laggage",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@types/node": "^18.0.0",
    "@types/webpack": "^5.28.0",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss-loader": "^7.0.0",
    "shx": "^0.3.4",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "ts-node": "^10.8.2",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

package.json文件生成typescript声明文件所在的路径(可以参考typescript官网:Including declarations in your npm package):

package.json

{
  "name": "loaf",
  "version": "1.0.0",
  "description": "A demo shows how to create & build a javascript library with webpack & typescript",
  "main": "index.js",
  "typings": "./typings",
  "scripts": {
    "build": "shx rm -rf dist/** && npm run build:umd && npm run build:lib-esm",
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "build:lib-esm": "tsc -p tsconfig.json --declarationDir ./dist/typings -m es6 --outDir dist/lib-esm",
    "test": "npm run test"
  },
  "keywords": [
    "demo"
  ],
  "author": "laggage",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@types/node": "^18.0.0",
    "@types/webpack": "^5.28.0",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss-loader": "^7.0.0",
    "shx": "^0.3.4",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "ts-node": "^10.8.2",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

package.json中添加exports配置声明模块导出路径

package.json中的exports字段用于告诉使用者引用此库时从哪里寻找对应的模块文件. 比如使用者可能通过esm模块引用此库:

import { Foo } from 'loaf';
const foo = new Foo();

此时如果我们的package.json中没有指定exports字段, 那么模块系统会去寻找node_modules/index.js, 结果肯定是找不到的, 因为我们真正的esm格式的输出文件应该是在node_modules/loaf/lib-esm中的

于是我们可以这样来配置exports:

package.json

{
  "name": "loaf",
  "version": "1.0.0",
  "description": "A demo shows how to create & build a javascript library with webpack & typescript",
  "main": "index.js",
  "typings": "./typings",
  "exports": {
    "./*": "./lib-esm/*",
    "./umd/*": "./umd"
  },
  "scripts": {
    "build": "shx rm -rf dist/** && npm run build:umd && npm run build:lib-esm",
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "build:lib-esm": "tsc -p tsconfig.json --declarationDir ./dist/typings -m es6 --outDir dist/lib-esm",
    "test": "npm run test"
  },
  "keywords": [
    "demo"
  ],
  "author": "laggage",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.18.6",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@types/node": "^18.0.0",
    "@types/webpack": "^5.28.0",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.0.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss-loader": "^7.0.0",
    "shx": "^0.3.4",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.3",
    "ts-node": "^10.8.2",
    "typescript": "^4.7.4",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

用api-extractor提取出干净的.d.ts

在上面的用tsc输出esm和类型声明文件这一段中, 我们通过tsc命令输出了typescript了类型声明文件到dist/types目录下, 这个目录下有两个.d.ts文件, 分别是bar.d.tsfoo.d.ts, 通常是希望这些声明文件都在一个文件index.d.ts中的, 如果他们分散开了, 以本库为例, 如果我要使用本库中的Bar类, 那么我可能需要这样来导入:

import { Bar } from 'loaf/typings/bar';

我不觉得的这种导入方式是好的做法, 理想的导入方式应该像下面这样:

import { Bar } from 'loaf';

所以接下来, 还要引入微软提供的api-extractor

配置使用API extractor

安装依赖:

npm install -D @microsoft/api-extractor

再全局安装下:

npm install -g @microsoft/api-extractor

生成api-extractor.json

api-extractor init

稍微修改下api-extractor.json

<

api-extractor.json

{
...
  "scripts": {
    "build": "shx rm -rf dist/** && npm run build:umd && npm run build:lib-esm && npm run build:extract-api",
    "build:umd": "webpack -c webpack.config.ts --node-env production --env NODE_ENV=production",
    "build:lib-esm": "tsc -p tsconfig.json --declarationDir ./dist/typings-temp -m es6 --outDir dist/lib-esm",
    "build:extract-api": "api-extractor run && shx rm -rf dist/typings-temp",
    "build:extract-api-local": "shx mkdir -p ./etc && npm run build:lib-esm && api-extractor run -l",
    "test": "npm run test"
  },
 ...
}

更新package.json

/**
 *
 * @internal
 */
export class Bar {
  bar() {}
}

注意, 这里处理新增了一个build:extract-api到scripts配置中, 还修改了build:lib-esm的配置, 将其输出的typescript类型声明文件放到了, typings-temp目录中, 最后这个目录是要删除; 还要注意, 每次提交代码到版本管理工具前, 要先运行npm run build:extract-api-local, 这个命令会生成./etc/<libraryName>.api.md文件, 这个文件是api-extractor生成的api文档, 应该要放到版本管理工具中去的, 以便可以看到每次提交代码时API的变化.

用@internal标注只希望在内部使用的class

比如, 我希望Bar类不能被此库的使用者使用, 我可以加上下面这段注释

/**
 *
 * @internal
 */
export class Bar {
  bar() {}
}

然后来看看生成的index.d.ts文件:

/**
 *
 * @internal
 */
declare class Bar {
    bar(): void;
}

export declare class Foo {
    private _bar;
    constructor(_bar?: Bar);
    foo(): void;
    loaf(): void;
}

export { }

可以看出index.d.ts文件中虽然declare了Bar, 但是并未导出Bar

这个特性是由api-extractor提供的, 更多api-extractor的内容移步官方文档

小结

至此, 我们就可以构建一个可以通过诸如AMD CommonJs esm等js模块系统或是使用script标签的方式引用的js库了, 主要用到了webpack typescript api-extractor这些工具. 完整的示例代码可以访问github-laggage/loaf查看.

到此这篇关于typescript+webpack构建一个js库的文章就介绍到这了,更多相关webpack构建js库内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • webpack搭建脚手架打包TypeScript代码

    创建文件夹 目录结构: dabaots 初始化 npm init -y生成package.json文件 目录结构: dabaots dabaots / package.json 然后在开发环境中安装以下几个工具 npm i -D webpack··························(打包代码的核心工具 webpack-cli·····················(webpack的命令行工具) typescript ·······················(写ts所需的核心

  • 浅谈TypeScript 用 Webpack/ts-node 运行的配置记录

    公司项目代码是用 TypeScript 写的, 中间遇到有些代码不要放到 Node 里面去跑. 具体场景一些路由配置, 比较大的一块 JSON 数据定义在 TypeScript 里. 我另外有增加脚本, 基于这些 JSON 数据用来生成切换路由的函数. 这就需要运行 TypeScript 了, 而且可能包含一些额外的业务代码. 首先 Node 运行 TypeScript 有提供 ts-node 用来处理. ts-node 会先编译 TypeScript 代码到 JavaScript, 再调用 N

  • 如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)

    1.导语 首先来简单介绍一下webpack:现代 JavaScript 应用程序的 静态模块打包工具 .当 webpack 处理应用程序时,它会在内部构建一个会映射项目所需的每个模块 的依赖图(dependency graph),并生成一个或多个 bundle .webpack4.0出现之后,我们可以不用再引入一个配置文件来打包项目,并且它仍然有着很高的可配置性,可以很好满足我们的需求. 在开始正文之前,首先先来看看我们要实现的成果: 支持ES6+JQuery+Less/Scss的单页/多页脚手

  • 使用webpack/gulp构建TypeScript项目的方法示例

    总体来看,TypeScript项目构建主要分两步: 将ts 项目整体转换为js项目 按常规套路,对该 js 项目进行打包构建 构建过程中,对 ts 文件的转换不再使用命令行方式,所以 tsc 的配置参数,需要通过 tsconfig.json 文件设置. 初始化 tsconfig.json tsc --init 之后,我们会在项目目录中得到一个完整冗长的 tsconfig.json 配置文件.这个文件暂且不必改动. { "compilerOptions": { /* Basic Opti

  • 教你使用webpack打包编译TypeScript代码

    TypeScript打包 webpack整合 通常情况下,实际开发中我们都需要使用构建工具对代码进行打包: TS同样也可以结合构建工具一起使用,下边以webpack为例介绍一下如何结合构建工具使用TS: 步骤如下: 初始化项目 进入项目根目录,执行命令 npm init -y,创建package.json文件 下载构建工具 命令如下: npm i -D webpack webpack-cli webpack-dev-server typescript ts-loader clean-webpac

  • React+TypeScript+webpack4多入口配置详解

    资源 React-16.8.* react-router-dom-4.3.* TypeScript-3.5.* webpack-4.* eslint-5.16.* 项目目录 ├── dist # 打包结果目录 │ ├── demo1 //类别demo1的打包结果 │ │ ├── demo1.himl │ │ ├── demo1.js │ │ └── demo1.css │ └── demo2 ... //类别demo2的打包结果 ├── src # 业务资源文件目录 │ ├── category

  • 使用typescript+webpack构建一个js库的示例详解

    目录 入口文件 tsconfig配置 webpack配置文件 webpack入口文件配置 webpack为typescript和less文件配置各自的loader webpack的output配置 运行webpack进行打包 测试验证 输出esm模块 已经输出了umd格式的js了, 为什么还要输出esm模块? ----TreeShaking 用tsc输出esm和类型声明文件 package.json中添加exports配置声明模块导出路径 完善package.json文件 用api-extrac

  • 在一个页面重复使用一个js函数的方法详解

    1.给每个拥有相同行为的问题DOM节点一个相同的class类,如question,同时给不同的问题一个不同的标识ID如 id="question1" id="question2"...诸如此. 2.给类.question绑定点击事件,在触发函数里面先判断当前点击的这个类的id,即可知道你要操作的是哪一个问题,然后调用你的那个伸缩函数即可. <!DOCTYPE html> <html> <head lang="en"&

  • JS实现一个微信录音功能过程示例详解

    目录 功能原型图 拆解需求 评估时间 代码实现 功能原型图 其实就是微信发送语音的功能.没有转文字的功能. 拆解需求 根据原型图可以很容易的得出我们需要做的内容包括下面三个部分: 接入微信的语音SDK 调用微信SDK的API逻辑 界面和交互的实现 其中第一点和第二点属于业务逻辑部分,第三点属于交互逻辑部分.对于业务逻辑和交互逻辑的关系在我的另外一篇文章描述过,我在vue中是这样拆分组件的 从原型图可以分析出如下的流程图: 评估时间 第三事情是评估时间.在接到这个需求的时候,我们需要假设我们在此之

  • webpack 5.68.0版本教程示例详解

    目录 起步 1. 基本安装 2. 配置出入口 plugin 1. html-webpack-plugin 2. progress-bar-webpack-plugin loader 1. css-loader与style-loader 2. url-loader与file-loader 3. sass-loader 4. postcss-loader 5. babel-loader 搭建环境 1. 开发环境与生产环境 2. 配置别名 代码分离 1. webpack-bundle-analyzer

  • TypeScript前端上传文件到MinIO示例详解

    目录 什么是MinIO? 本地Docker部署测试服务器 上传的API TypeScript实现 1. XMLHttpRequest 2. Fetch API 3. Axios 从后端获取临时上传链接 上传文件 踩过的坑 1. presignedPutObject方式上传提交的方法必须得是PUT 2. 直接发送File即可 3. 使用Axios上传的时候,需要自己把Content-Type填写成为file.type 示例代码 什么是MinIO? MinIO 是一款高性能.分布式的对象存储系统.

  • python可视化大屏库big_screen示例详解

    目录 big_screen 特点 安装环境 输入数据 本地运行 在线部署 对于从事数据领域的小伙伴来说,当需要阐述自己观点.展示项目成果时,我们需要在最短时间内让别人知道你的想法.我相信单调乏味的语言很难让别人快速理解.最直接有效的方式就是将数据如上图所示这样,进行可视化展现. 具体如下: big_screen 特点 便利性工具, 结构简单, 你只需传数据就可以实现数据大屏展示. 安装环境 pip install -i https://pypi.tuna.tsinghua.edu.cn/simp

  • python进阶collections标准库使用示例详解

    目录 前言 namedtuple namedtuple的由来 namedtuple的格式 namedtuple声明以及实例化 namedtuple的方法和属性 OrderedDict popitem(last=True) move_to_end(key, last=True) 支持reversed 相等测试敏感 defaultdict 小例子1 小例子2 小例子3 Counter对象 创建方式 elements() most_common([n]) 应用场景 deque([iterable[,

  • Three.js引入Cannon.js及使用示例详解

    目录 引言 大体代码及效果 Cannon.js 打造当前 UI 引言 在开始之前,我们还是要解释下什么是 Cannon.js 以及它的作用. Cannon.js 是一个 3D 物理引擎,通过为物体赋予真实的物理属性的方式来计算运动.旋转和碰撞检测.Cannon.js 相较于其他常见的物理引擎来说,比较轻量级而且完全通过 JavaScript 来实现. Cannon.js 的官方文档地址为 schteppe.github.io/cannon.js/ ,从官方介绍中也可以看到很多有趣的例子,如下所示

  • C语言编程gcc如何生成静态库.a和动态库.so示例详解

    目录 一.什么是静态库和动态库 二.gcc生成.a静态库和.so动态库 1.生成静态库(.a) 1.1编辑生成例子程序hello.h.hello.c和main.c 1.2将hello.c编译成.o文件 1.3由.o文件创建静态库 1.4在程序中使用静态库 1.5验证静态库的特点 2.生成动态库(.so) 2.1由.o文件创建动态库文件 2.2在程序中使用动态库 三.实例 1.实例1 1.1代码 1.2 静态库.a文件的生成与使用 1.3 动态库.so文件的生成与使用 2.实例2 2.1代码 2.

  • 30分钟用Node.js构建一个API服务器的步骤详解

    Node.js 对初学者来说可能是令人望而却步的,其灵活的结构和缺乏严格的规范使它看起来很复杂. 本教程是 Node.js,Express 框架和 MongoDB 的快速指南,重点介绍基本的 REST 路由和基本的数据库交互.你将构建一个简单的 API 框架模版,然后可以将其用作任何应用. 本教程适用于:你应该对 REST API 和 CRUD 操作有基本的了解,还有基本的 JavaScript 知识.我用的是 ES6(主要是箭头函数),但并不是很复杂. 在本教程中,我们将为创建一个网络笔记应用

随机推荐