webpack项目基础配置
- webpack版本
webpack-cli: 5.1.4
webpack: 5.91.0
- 新建项目文件夹ts-animates-webpack-demo
- pnpm初始化
pnpm init
,根目录下生成package.json文件
{
"name": "ts-animates-webpack-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
}
- 新建src/dist目录
- 全局安装过webpack、webpack-cli
- 根目录下新建webpack配置文件webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.ts',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
}
webpack处理ts
- 安装typescript、ts-loader
- 添加webpack配置
module: {
rules: [
{
test: /\.(ts)$/,
loader: 'ts-loader'
}
]
}
- 添加tsconfig.json配置文件
{
"compilerOptions": {
"sourceMap": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
- 在src目录下创建index.ts文件
- 执行
pnpm run dev
,dist文件夹下生成main.js文件,内容如下:
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./src/index.ts":
(() => {
eval("var num = 1;\nconsole.log(num);\n\n\n//# sourceURL=webpack://ts-animates-webpack-demo/./src/index.ts?");
/***/ })
/******/ });
/******/ var __webpack_exports__ = {};
/******/ __webpack_modules__["./src/index.ts"]();
/******/
/******/ })()
;
webpack处理图片
- 官方文档介绍
- webpack5 无需安装loader,直接配置规则如下:
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
}
]
}
- 默认会将图片输出到dist目录下,可在output——assetModuleFilename中配置如下内容,可将图片打包到dist/images文件夹下
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
assetModuleFilename: 'images/[hash][ext][query]'
},
webpack处理vue
- 安装vue、vue-loader
- webpack配置模块规则
module: {
rules: [
{
test: /\.vue/,
loader: 'vue-loader'
}
]
},
- 在入口index.ts文件中创建app实例并挂载
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
报错:“找不到模块./App.vue或其相应的类型声明:”
解决方案如下:
- 在根目录创建vue.d.ts声明文件
declare module "*.vue" {
import { defineComponent } from 'vue'
const Component: ReturnType<typeof defineComponent>
export default Component
}
- 在tsconfig.json配置文件中加入vue.d.ts
"include": [
"src/**/*","vue.d.ts"
],
报错:export 'render' (imported as 'render') was not found
export 'render' (imported as 'render') was not found in './App.vue?vue&type=template&id=7ba5bd90&ts=true' (possible exports: __esModule) @ ./src/index.ts 4:16-36
解决方案:ts-loader规则增加options配置如下:
vue 单文件组件中假如使用了
lang="ts"
,ts-loader
需要配置appendTsSuffixTo: [/.vue$/]
,用来给.vue
文件添加个.ts
后缀用于编译。
module: {
rules: [
{
test: /\.(ts)$/,
loader: 'ts-loader',
options: {
configFile: path.resolve(process.cwd(), 'tsconfig.json'),
appendTsSuffixTo: [/\.vue$/]
},
},
]
}
报错:TS2307: Cannot find module './assets/11.jpg' or its corresponding type declarations.
解决方案:在根目录下新增images.d.ts配置文件
declare module '*.jpg' {
const value: string
export default value
}
tsconfig.json文件修改如下:
"include": [
"src/**/*","*.d.ts"
],
问题:图片展示失败
__webpack_require__加载的图片返回的结果没有default属性
解决方案:修改tsconfig.js配置文件
"compilerOptions": {
"sourceMap": true,
"module": "ES6",
"moduleResolution": "Node"
},
target
指定模块解析策略:
Default:
Classic
if isAMD
,UMD
,System
, orES6
/ES2015
; Matches if isnode16
ornodenext
;Node
otherwise.Allowed:
classic
node10
/node
node16
nodenext
bundler
默认是ES3
es3
es5
es6
/es2015
es2016
es2017
es2018
es2019
es2020
es2021
es2022
esnext
module
Default:
CommonJS
if isES3
orES5
;ES6
/ES2015
otherwise.Allowed:
none
commonjs
amd
umd
system
es6
/es2015
es2020
es2022
esnext
node16
nodenext
preserve
module为commonjs时的转换结果:
b.js
export let getTime = new Date()
export default function add(a, b) {
return a + b
}
index.js
import b from './b'
console.log(b)
commonJS时的转换结果:
"./src/example/modules/b.js":
((__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */
__webpack_require__.d(__webpack_exports__, {
/* harmony export */
"default": ()=>(/* binding */
add),
/* harmony export */
getTime: ()=>(/* binding */
getTime)/* harmony export */
});
let getTime = new Date()
function add(a, b) {
return a + b
}
/***/
}
),
/***/
"./src/example/modules/index.js":
((__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */
var _b__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./b */
"./src/example/modules/b.js");
console.log(_b__WEBPACK_IMPORTED_MODULE_0__["default"])
/***/
}
)
/******/
});
moduleResolution
模块解析; 应该从什么位置寻找模块
- classic 经典
- node 和node解析模块一致(唯一的变化,是将js替换为ts)
webpack处理css文件
- 安装style-loader、css-loader
- 配置module-rules
{
test: /\.css/,
use: ['style-loader', 'css-loader']
}
html-webpack-plugin插件指定index.html
- 安装html-webpack-plugin
- 在webpack.config.js文件中配置该插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
- 根目录下新增index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
</body>
</html>
webpack-dev-server
- 安装webpack-dev-server
- package.json文件中的script修改如下
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server"
},
加入vue-router
- 安装vue-router
- src目录下新建router文件夹,再建index.ts文件, 内容如下:
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../pages/home.vue'
import CssFlex from '../pages/CssFlex.vue'
const routes = [
{
path: '/',
component: Home
},
{
path: '/css/flex',
component: CssFlex
}
]
const router = createRouter({
history: createWebHashHistory(),
routes,
})
export default router
- src目录下的index.ts文件,内容修改如下:
import { createApp } from 'vue'
import App from './App.vue'
import Router from './router/index'
const app = createApp(App)
app.use(Router)
app.mount('#app')
报错:Module not found: Error: Can't resolve './router/index'
ERROR in ./src/index.ts 3:0-36
Module not found: Error: Can't resolve './router/index'
需要在webpack.config.js文件中配置resolve/extensions,默认值['.js', '.json', '.wasm']
resolve: {
extensions: ['.ts', '.js']
}
- 修改src目录下的App.vue文件如下:
<template>
<nav class="left">
<router-link to="/css/flex" class="link">CSS flex</router-link>
</nav>
<router-view class="right">
</router-view>
</template>
<script setup lang="ts">
import { RouterLink, RouterView} from 'vue-router'
</script>
使用Scss
- 安装sass-loader / sass
- 配置module/rules如下:
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}
报错: at-rule or selector expectedcss(css-ruleorselectorexpected)
解决方案:vscode打开设置,把下面的勾选去掉