webpack 从零开始配置教程

写这篇文章的时候 webpack 5 刚发布不久,相关插件生态还没跟进升级,所以这篇文章使用的版本为 webpack 4

  • 示例代码已上传gitee:webpack-demo
  • 为了避免插件版本的兼容问题,以下安装个别npm依赖时我会指定版本号,但很多插件的最新版本是适配webpack 5的,最好参考已上传示例代码里的package.json文件来安装插件指定版本。
  • webpack 5 的配置其实和 4 相差不大,只需要在npm官网查看插件文档的配置说明,有变化的再进行适配就行。
  • 本文是在研读参考了vue-clicreate-react-app的配置源码后书写的,且是自己从零开始一行一行敲出来的,所以内容质量有保证,可放心食用。

(本文仅作为webpack学习之用,实际项目中还是更推荐使用成熟的脚手架搭建,然后根据本文教程去定制改造。)

一、基础

1、目录文件

新建一个文件夹作为示例项目,项目根目录运行命令初始化package.json

npm init -y

然后按照以下目录先创建空文件:
在这里插入图片描述

2、入口entry、出口output

  • 安装webpack依赖
npm i -D webpack@4.44.2 webpack-cli@3.3.12
  • /config/webpack.base.config.js 写入内容:
const path = require('path')

module.exports = {
  entry: { // 入口配置
    app: './src/index.js'
  },
  output: { // 出口配置
  	filename: 'js/[name].[contenthash:8].js',
  	path: path.resolve(__dirname, '../dist'),
  }
}
  • package.json 里写入script命令:
"script": {
  "build": "webpack --config ./config/webpack.base.config.js"
}
  • 然后就可以运行查看效果了:
npm run build
  • 正常的话,会在项目根目录生成dist文件夹,里面就是打包后的文件。
    在这里插入图片描述
  • hashchunkhashcontenthash 的区别:
    hash 是每次打包时重新生成,所有文件共用同一个hash;
    chunkhash 根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。在生产环境中会将一些公共库分离出来,公共库不改变,生成的chunkhash值就不变。
    contenthash 和文件内容相关,内容不变,生成的哈希值就不变。webpack里css也属于js的一部分,所以chunkhash下css内容改变,对应js的hash也会变,而contenthash下只会改变该css的hash(使用css和js分离后)。

3、html模板 html-webpack-plugin

使用 html-webpack-plugin 插件来配置html模板文件的关联,这样打包后的js、css等会自动引入到html中,就可以访问html文件查看效果了。

  • 安装插件:
npm i -D html-webpack-plugin@4.5.0
  • /config/webpack.base.config.js 添加plugins,配置html-webpack-plugin:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: ......,
  output: ......,
  // 在这里添加
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
      inject: 'body',
      hash: false
    }),
  ],
}
  • /public/index.html 写入代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
  <title>Title</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
  • /src/index.js 写入代码:
console.log('小王子')
  • 最后运行命令打包:npm run build,打包后会在dist下生成index.html,打开该html查看控制台输出效果。

4、js编译 react、babel

用哪个框架都行,目的都是学习webpack的配置,以react示例。

  • 安装react依赖:
npm i -S react react-dom
  • /src/index.js 替换为以下代码:
import React from 'react'
import ReactDOM from 'react-dom'

function App () {
  return (
    <div>
      <div className="test">小王子</div>
    </div>
  )
}

ReactDOM.render(
  <App/>, 
  document.getElementById('root')
)
  • 添加babel:
    由于react使用的jsx语法,不是js标准语言语法,所以需要借助babel插件来转码,当然babel用处远不止这些,比如用babel将es6+代码转为兼容性更好的代码。
    安装babel相关依赖:
npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react
  • babel.config.js 写入代码:
module.exports = {
  presets: [
    '@babel/preset-env', 
    '@babel/preset-react'
  ],
}
  • /config/webpack.base.config.js 添加module,配置babel的rules:
const path = require('path')

module.exports = {
  entry: ......,
  output: ......,
  plugins: ......,
  // 在这里添加代码
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        options: {
          cacheDirectory: true
        },
        loader: 'babel-loader'
      }
    ]
  }
}
  • 运行 npm run build,然后打开打包后的index.html查看效果。

5、配置分离 webpack-merge

webpack配置里可以指定mode属性来把运行环境划分为development和production,
使用webpack-merge插件可以针对不同mode环境使用不同的webpack配置,插件帮我们智能合并配置。

  • 安装依赖:
npm i -D webpack-merge@4.2.2
  • /config/webpack.dev.config.js 写入代码:
const merge = require('webpack-merge')
const common = require('./webpack.base.config')

module.exports = merge(common, {
  mode: 'development',
  output: {
    filename: 'js/[name].js',
  },
})
  • /config/webpack.prod.config.js 写入代码:
const merge = require('webpack-merge')
const common = require('./webpack.base.config')

module.exports = merge(common, {
  mode: 'production',
})
  • package.json 里修改scripts命令:
"scripts": {
  "start": "webpack --config ./config/webpack.dev.config.js",
  "build": "webpack --config ./config/webpack.prod.config.js"
},

注意build命令里的webpack.base.config.js换成了webpack.prod.config.js。
这样就分了开发环境和生产环境。

6、清空目录 clean-webpack-plugin

使用clean-webpack-plugin插件可以在build打包之前自动删除上次打包的dist文件夹,防止冗余文件的产生。

  • 安装依赖:
npm i -D clean-webpack-plugin
  • /config/webpack.prod.config.js 里添加plugins配置:
const merge = require('webpack-merge')
const common = require('./webpack.base.config')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = merge(common, {
  mode: 'production',
  // 在这里添加代码
  plugins: [
    new CleanWebpackPlugin(),
  ],
})
  • npm run build 查看dist文件夹还有没有之前遗留的js文件。

7、热更新 webpack-dev-server

使用webpack-dev-server插件,在webpack运行时自动启动一个本地服务器运行打包后的html文件,配合热更新,实现代码改动后实时查看效果。

  • 安装依赖:
npm i -D webpack-dev-server@3.11.0
  • /config/webpack.dev.config.js 里添加devServer和plugins配置:
const merge = require('webpack-merge')
const common = require('./webpack.base.config')
const webpack = require('webpack')

module.exports = merge(common, {
  mode: 'development',
  output: {
    filename: 'js/[name].[hash:8].js',
  },
  // 在这里添加代码
  devServer: {
    open: true,
    port: 9000,
    compress: true,
    hot: true,
    inline: true,
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
  ],
})
  • package.json 里修改scripts的start命令:
"start": "webpack-dev-server --inline --progress --config ./config/webpack.dev.config.js",
  • npm start 查看效果。

8、源码追踪 devtool、source map

devtool用于配置source map选项,帮助我们调试时追踪原始源代码,有多种source map格式供选择,具体可以参考文档,综合构建速度和使用效果,建议选择 cheap-module-eval-source-map,各方面都比较均衡。

  • /config/webpack.dev.config.js 里添加devtool配置:
module.exports = merge(common, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map', // 在这里添加即可
  output: ......,
  devServer: ......,
  plugins: ......,
})
  • /src/index.js 里添加一条console语句:
import React from 'react'
import ReactDOM from 'react-dom'

console.log(123) // 在这里添加即可

function App () {
  ......
}
......
  • 在chrome控制台找到打印结果行,点击该行右侧的文件路径查看源代码,通过对比添加和不添加devtool时的源码来理解source map的作用。

9、样式相关 loader

style-loader 用于创建样式标签引入css代码,不能单独使用;
css-loader 用于解析css文件生成css代码,给style-loader使用;
less-loader 用于将less文件转换为css文件,给css-loader使用;

  • 安装依赖:
npm i -D style-loader css-loader less less-loader
  • src文件夹下创建文件index.less
@color: red;

.test {
  color: @color;
}
  • /src/index.js 引入该less使用:
import React from 'react'
import ReactDOM from 'react-dom'
import './index.less'

function App () {
  return (
    <div>
      <div className="test">小王子</div>
    </div>
  )
}

ReactDOM.render(
  <App/>, 
  document.getElementById('root')
)
  • /config/webpack.base.config.js 里配置loader:
module.exports = {
  module: {
    rules: [
      ......
      // 接上,追加以下代码
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'less-loader']
      },
    ]
  }
}

rules里的use数组在解析时是按从右往左解析的,需要注意顺序。

10、css工具集 postcss

postcss 是一个允许使用 JS 插件转换样式的工具集合;
postcss-loader 用于webpack中对css做进一步处理的loader;
autoprefixer 属于postcss的一个插件,配合postcss-loader可以自动给css样式添加浏览器前缀,以兼容低版本浏览器;
browserlist 用于指定项目运行的目标浏览器范围,能被autoprefixer和babel等识别,根据目标浏览器范围做兼容适配。

  • 安装依赖:
npm i -D postcss postcss-loader autoprefixer browserlist
  • /src/index.less添加样式:
@color: red;

.test {
  color: @color;
  display: flex;
  justify-content: center;
}
  • /config/webpack.base.config.js 里修改css和less的loader配置:
module.exports = {
  module: {
    rules: [
      ......
      // 修改css和less的loader配置
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.less$/,
        use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
      },
    ]
  }
}
  • 项目根目录新建文件 postcss.config.js
module.exports = {
  plugins: {
    autoprefixer: {}
  }
}
  • package.json 里添加browserlist配置:
{
  "dependencies": ......,
  "devDependencies": ......,
  ---在这里追加---
  "browserslist": [
    "> 1% in CN",
    "last 2 versions"
  ]
}
  • npm start 运行,chrome开发者工具查看文字的css样式,看flex相关样式是否自动加上了浏览器前缀。

11、文件处理 file-loader、url-loader

file-loader用于打包静态文件并将引入路径和js关联;
url-loader用于处理图片资源的打包,低于指定大小时会将资源转换为base64格式使用,其他情况处理和file-loader一样。

  • 安装依赖:
npm i -D file-loader url-loader
  • /config/webpack.base.config.js 里添加loader配置:
module.exports = {
  module: {
    rules: [
      ......
      // 接上,追加以下代码
      {
        test: /\.(jpe?g|png|gif)$/i,
        options: {
          esModule: false,
          limit: 4096, // 配置低于4k的图片会转为base64格式
        },
        loader: 'url-loader',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i, // 处理字体文件
        options: {
          esModule: false
        },
        loader: 'file-loader'
      },
    ]
  }
}

12、js压缩 terser-webpack-plugin

terser-webpack-plugin 用于对js做代码压缩及代码混淆等处理,对es6+支持更好,替代以前的uglifyjs-webpack-plugin。

  • 安装依赖:
npm i -D terser-webpack-plugin@4.2.3
  • /config/webpack.prod.config.js 里添加配置:
const TerserWebpackPlugin = require('terser-webpack-plugin')

module.exports = merge(common, {
  mode: 'production',
  plugins: ......,
  // 在这里添加
  optimization: {
    minimize: true,
    minimizer: [
      new TerserWebpackPlugin({
	    terserOptions: {
          compress: { 
            pure_funcs: ['console.log'] // 删除console.log代码
          }
        }
      }),
    ],
  },
})

13、css分离 mini-css-extract-plugin

mini-css-extract-plugin用于将打包后的css单独抽离出来,webpack打包时默认是将css整合进js里通过动态创建style标签实现的,而这个插件将css剥离出来,能减少不必要的js代码及dom操作,提升页面加载性能。

  • 安装依赖:
npm i -D mini-css-extract-plugin
  • /config/webpack.base.config.js 里配置plugins和loader:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
  plugins: [
    ......,
    // 接上,在这里追加
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash:8].css',
      chunkFilename: 'css/[id].[contenthash:8].css',
      ignoreOrder: true
    }),
  ],
  module: {
    rules: [
      // 修改css和less的loader,替换掉style-loader
	  {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'less-loader']
      },
    ]
  }
}
  • npm run build 查看打包目录是否生成单独的css文件。
  • 注意:mini-css-extract-plugin需要配合html-webpack-plugin才能自动加载到html上,否则只会分离,不会自动引入。

14、css压缩 optimize-css-assets-webpack-plugin

optimize-css-assets-webpack-plugin 插件用于对css文件做压缩处理,默认使用cssnano压缩。
需要配合mini-css-extract-plugin插件,先将css分离后再压缩。

  • 安装依赖:
npm i -D optimize-css-assets-webpack-plugin
  • /config/webpack.prod.config.js 里添加plugins:
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

module.exports = merge(common, {
  plugins: [
    ......,
    // 接上,在这里追加
    new OptimizeCssAssetsPlugin(),
  ]
})
  • npm run build 查看打包后的css文件是否已被压缩。

15、快捷路径 alias

alias是webpack内置支持的一个属性,用来指定快捷路径标识,配置后就能方便的书写引入路径。

  • /config/webpack.base.config.js里配置:
module.exports = {
  entry: ......,
  output: ......,
  // 接上,在这里追加
  resolve: {
    alias: {
      '@': path.resolve(__dirname, '../src'),
    }
  },
}
  • /src/index.js修改文件的引入路径:
import './index.less' 替换为 import '@/index.less'
  • npm start查看是否正常运行

二、进阶

1、chunk分离 splitChunks

splitChunks用于代码分离,有利于性能优化。模块是否分离的判断原则:体积大、稳定不变。

  • 浏览器在加载文件后会将其缓存下来,下次加载该文件时直接从本地缓存里读取,加快访问速度。
  • webpack打包默认会将import同步引入的代码打包成一个文件,而使用splitChunks可以将该文件分离成多个。
  • 分离稳定不变的代码能保证每次打包后分离出来的文件保持不变,这样分离后的文件就能被浏览器缓存且缓存不会在项目更新发布后失效,这就是splitChunks的主要作用。
  • /config/webpack.pord.config.js添加splitChunks:
module.exports = merge(common, {
  optimization: {
    ......,
    // 接上,在这里追加
    splitChunks: {
      chunks: 'all',
      maxAsyncRequests: 8,
      maxInitialRequests: 6,
      minSize: 10000,
      cacheGroups: {
        react: { // 分离react和react-dom
          name: 'chunk-react',
          test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, // 匹配规则
          priority: 20 // 匹配优先级
        },
        vendors: { // 其他npm依赖(生产环境)
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: { // 组件公共抽离
          name: 'chunk-common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    }
  },
})
  • /config/webpack.dev.config.js里添加chunkFilename:
module.exports = merge(common, {
  output: {
    filename: 'js/[name].js',
    // 在这里添加
    chunkFilename: 'js/[name].js',
  },
})
  • /config/webpack.base.config.js里添加chunkFilename:
module.exports = {
  output: {
    filename: 'js/[name].[contenthash:8].js',
    path: path.resolve(__dirname, '../dist'),
    // 在这里添加
    chunkFilename: 'js/[name].[contenthash:8].js',
  },
}
  • chunkFilename就是用来配置splitChunks分离出来的文件名
  • npm run build查看打包后的文件,多打包几次,对比分离出来的chunk文件名是否有变化。

2、自定义常量 DefinePlugin

DefinePlugin 是webpack内置的一个插件,允许创建一个在编译时可以配置的全局常量,配置后就可以在代码里使用这个常量了。

  • /config/webpack.base.config.js 里添加plugins:
const webpack = require('webpack')

module.exports = {
  plugins: [
    ......,
    // 接上,在这里追加
    new webpack.DefinePlugin({
      VERSION_H5: +new Date() // 这里添加了VERSION_H5
    }),
  ]
}

需要注意,如果给定义的常量赋值为string类型时需要带上原始引号,可以通过单引号包裹双引号的方式或通过JSON.stringify包裹,例如 ‘“abc”’ 或 JSON.stringify(‘abc’)

  • /src/index.js 里添加一条打印语句:
// 找个合适的地方添加就行
console.log(VERSION_H5)
  • npm start 查看chrome控制台输出结果是否符合预期

3、样式隔离 css modules

css modules是一种防止css样式污染的模块化解决方案。
接下来就配置.module.css或.module.less后缀的文件自动以css modules方式处理。

  • /config/webpack.base.config.js 里配置loader:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

// 为了代码简洁,在这里封装了一下
const cssTest = /\.css$/
const lessTest = /\.less$/
const cssModuleTest = /\.module\.css$/
const lessModuleTest = /\.module\.less$/
const baseCssUse = [
  MiniCssExtractPlugin.loader, 
  'css-loader', 
  'postcss-loader'
]
const baseCssModuleUse = [
  MiniCssExtractPlugin.loader, 
  {
    loader: 'css-loader',
    options: {
      modules: {
        localIdentName: "[name]_[local]__[hash:5]"
      }
    },
  }, 
  'postcss-loader'
]

module.exports = {
  module: {
    rules: [
      ......,
      // 把之前的css和less的配置 替换成以下代码
      {
        test: cssTest,
        exclude: cssModuleTest,
        use: baseCssUse
      },
      {
        test: lessTest,
        exclude: lessModuleTest,
        use: [...baseCssUse, 'less-loader']
      },
      {
        test: cssModuleTest,
        use: baseCssModuleUse
      },
      {
        test: lessModuleTest,
        use: [...baseCssModuleUse, 'less-loader']
      },
      ......,
    ]
  },
}
  • src目录下新建index.module.less:
.name {
  text-decoration: line-through;
}
  • /src/index.js添加代码:
import style from './index.module.less'

function App () {
  return (
    <div>
      <div className='test'>小王子</div>

      <div className={style.name}>Neo</div>

      <div>
        <img src={icon} alt=""/>
      </div>
    </div>
  )
}
  • 配置完后,npm start重启项目,chrome控制台查看元素及样式效果。

4、兼容处理 polyfill

es6包含新的语法和新的api,新api是用更底层的语言实现的,新语法默认可以被babel降级处理,但新api默认不会处理,例如数组的find、Object.assign、promise等,需要配置polyfill来处理。
从babel v7.4版本开始,官方不再推荐使用@babel/polyfill,更推荐直接使用core-js/stable和regenerator-runtime/runtime。

  • 安装依赖:
npm i -S core-js regenerator-runtime
  • 在入口文件/src/index.js里最顶部导入:
// 必须在入口文件最顶部导入
import "core-js/stable"
import "regenerator-runtime/runtime"

// 然后再导入其他的
......
  • babel.config.js里修改@babel/preset-env配置:
module.exports = {
  presets: [
    // 在这里修改 @babel/preset-env 的配置
    [
      '@babel/preset-env',
      {
        modules: false,
        useBuiltIns: 'entry',
        corejs: {
          version: '3.8', // 你的core-js版本号前两位
          proposals: true,
        },
      },
    ],
    // 其他的保持不变
    ......
  ],
}
  • 以上是我个人推荐的配置方式,缺点是有全局命名空间的污染,但优点是支持更全,其他诸如 useBuiltIns: usage 以及 @babel/plugin-transform-runtime 方式的优缺点正好相反,参考文档

5、代理 proxy

实际项目中,本地开发一般都会遇到接口跨域的问题,协议、域名、端口号 这三项任意一项不一致就会跨域,在devServer里配置proxy代理可以解决跨域问题。

  • 在配置代理之前,最好在你的所有api请求地址之前都加一个代理标识,用于代理的匹配拦截,告诉代理服务器哪些请求需要被代理,这里就暂定代理标识为/proxy
  • /config/webpack.dev.config.js里配置devServer:
module.exports = merge(common, {
	devServer: {
	  contentBase: path.resolve(__dirname, '../dist'),
	  open: false,
	  port: 9000,
	  compress: true,
	  hot: true,
	  inline: true,
	  proxy: {
	      '/proxy': {
		        target: 'https://192.111:8800',
		        ws: true,
		        changeOrigin: true,
		        secure: false,
		        pathRewrite: {
		          '^/proxy': ''
		        }
		   }
      }
	},
})
  • target 目标地址,有端口号的需要带上端口号;
  • ws 配置是否支持 web socket;
  • changeOrigin 配置是否支持虚拟主机站点,我也不清楚具体啥意思;
  • secure 是否开启安全验证,目标地址为https时需设置secure为false;
  • pathRewrite 路径重写,上述是配置了代理后将/proxy替换为空字符串,即实际接口地址不再需要携带/proxy。
  • 更多配置参考http-proxy-middleware文档。

6、脚本变量 cross-env

cross-env是一款运行跨平台设置和使用环境变量的脚本。使用cross-env在scripts脚本命令里配置自定义变量可以实现命令行快捷切换环境配置的功能。

比如配置不同的测试环境使用不同的接口地址,传统方式可能是直接在devServer里修改proxy代理地址的代码,人工修改代码容易出错,在多人开发时也容易出现代码冲突,如果使用cross-env配置的变量进行判断设置对应的代理地址,通过切换scripts命令来切换代理就变的方便多了。

  • 安装依赖:
npm i cross-env -D
  • package.json里修改scripts:
"scripts": {
    "start": "npm run start:test1",
    "start:test1": "cross-env MY_TYPE=test1 webpack-dev-server --progress --config ./config/webpack.dev.config.js",
    "start:test2": "cross-env MY_TYPE=test2 webpack-dev-server --progress --config ./config/webpack.dev.config.js",
    "build": "webpack --config ./config/webpack.prod.config.js"
  },
  • 上述配置就是设置了MY_TYPE这个变量,两个命令设置的值分别是test1和test2,运行npm run start:test1时在webpack配置文件里就可以通过process.env.MY_TYPE获取到值。

cross-env自动把我们设置的变量加在了process.env这个对象上,但是process.env只能在node环境里获取到,而在浏览器环境里获取不到。

不过还记得上面第4条介绍的DefinePlugin吗,利用DefinePlugin我们可以添加个浏览器环境也能用的process.env对象,方式如下:

  • /config/webpack.base.config.js里定义DefinePlugin插件配置:
new webpack.DefinePlugin({
  // VERSION_H5: +new Date(),
  'process.env': Object.keys(process.env).reduce(
    (env, key) => {
      env[key] = JSON.stringify(process.env[key]);
      return env;
    }, 
    {}
  )
}),
  • 然后在/src/index.js里添加打印语句:
console.log(process.env.NODE_ENV)
console.log(process.env.MY_TYPE)
  • 分别运行命令npm run start:test1npm run start:test2查看浏览器打印结果。

7、ts的支持 ts-loader

如果项目使用typescript,需要额外配置。

  • 安装依赖:
npm i -D typescript@4.0.5 ts-loader@7.0.5
  • 项目根目录添加tsconfig.json文件,写入以下内容:
{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "allowJs": true
  }
}
  • /config/webpack.base.config.js里配置 resolve 和 loader:
module.exports = {
  module: {
  	resolve: {
  		......
  		// 接上,追加以下代码,表示引用文件时如果没带后缀会按照此顺序依次查找
  	    extensions: ['.tsx', '.ts', '.js'],
	},
	......,
    rules: [
      ......
      // 接上,追加以下代码
      {
        test: /\.tsx?$/,
        use: ['ts-loader']
      },
    ]
  }
}
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值