基础-前端工程化配置项目

前端工程化的核心就是webpack了,而光看官方不行,不能闭门造车啊,所以必须游离于各大社区,学习各位大佬的技术与见解,亲自动手配置项目才行。之前有提到一个前端工程化的学习之路,那包含了模块化、包管理器、构建工具、脚手架,这次的项目配置练习就多多少少涉及到其中的知识点了。

开搞,练习配置一个ts + vue的工程。

一、 构建项目初始目录

1. 生成ts的配置文件

命令:tsc --init

(tips:如果电脑是mac,且提示zsh: command not found: tsc,那就先安装ts,命令:sudo npm install typescript -g //全局安装typesrcpt)

现在这个文件报错哈,先配一下,让它去找src目录下的文件。

ts 复制代码
  {
     ...
     "include": [
       "src/**/*"
    ]
  }
  

2.生成package.json文件

命令:npm init -y

3.新增其他文件

webpack.config.jsindex.html

4.新建src文件夹

新增文件,main.jsApp.vueshim.d.ts

二、安装webpack依赖

这里就是涉及包管理构建工具的基础知识了。

1. 安装 webpack相关

依赖:webpackwebpack5以上需要一起安装webpack-cli

命令:npm i webpack webpack-cli -D

现在安装完这两个依赖就可以打包了,但开发的时候需要看效果哈,所以还得再本地开个服务,就是开发服务器哈。

依赖:webpack-dev-server

命令:npm i webpack-dev-server -D

现在和webpack相关的是安装完了。

还有配置一下打包和启动命令。

3.基本配置webpack.config.js

1. 基本打包配置

webpack是基于node.js环境的,所以按照CommonJs标准进行模块导出。 使用webpack提供的声明文件,则相关属性有智能提示。

js 复制代码
const { Configuration } = require("webpack"); //声明文件
const path = require("node:path");

/**
 * @type{Configuration}
 */

const config = {
  mode: "development",
  entry: "./src/main.ts", //入口文件
  output: path.resolve(__dirname, "dist"), //生成目录
  filename: "bundle.js", //打包后的文件
};

module.exports = config;

到这里已经是可以进行打包了,可以实验一下。

这样就是基本的打包功能已经实现了哈😉!!

2. 解析js语法配置

解析文件配的是loader,比如要支持scss预编译,配的就是loader

依赖:ts-loadertypescript

命令:npm i ts-loader typescript -D

js 复制代码
const config = {
    ...
    module: {
    rules: [
      { test: /\.ts$/, //正则,以ts结尾
       use: "ts-loader", //使用 loader
        exclude: /node_modules/ //除了这个模块
       }
      ],
  },
}

三、支持vue语法

1. 安装依赖

依赖:vue

命令:npm i vue

2.vue语法配置

js 复制代码
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);

app.mount("#app");
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>

现在是已经配置好了vue,但现在htmlwebpack还没有联系,那就需要让他们产生关联了。安装一个插件即可。 依赖:html-webpack-plugin

命令:npm i html-webpack-plugin -D

js 复制代码
//webpack.config.js
...
const HtmlWebpackPlugin = require("html-webpack-plugin");

const config = {
 ...
  plugins: [new HtmlWebpackPlugin({ template: "index.html" })], //webpack 的插件集合,都是对象,需要 new
  ...
};

这下打包的时候,就会以index.html为模板。

嘿嘿,是不是就可以npm run dev跑起来了? nonono😴,vue使用的是.vue结尾的文件,webpack不能编译啊,所以还得像之前一样,使用loader来处理。

依赖:vue-loader

命令:npm i vue-loader -D

js 复制代码
//webpack.config.js

const config = {
...
 module: {
    rules: [
      {
        test: /\.ts$/, //正则,以ts结尾
        use: "ts-loader", //使用 loader
      },
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
    ],
  },
};

这下wepack就能识别了,npm run dev来试试。。。。。 啊哦,报错了

啥意思,用过ts都多多少少会碰到,就是缺少对应的类型声明

.js 复制代码
  //shim.d.ts
  
  declare module "*.vue" {
  import { DefineComponent } from "vue";
  const component: DefineComponent<{}, {}, any>;
  export default component;
}

这下就好了。唉,还有报错:

说我们缺少了一个pugin,好,引入它。

js 复制代码
//webpack.config.js

...
const { VueLoaderPlugin } = require("vue-loader");

const config = {
 ...
  plugins: [
    new HtmlWebpackPlugin({ template: "index.html" }),
    new VueLoaderPlugin(),
  ], 
  ...
};

这下就没报错了,成功启动😎😎! vue的基本功能都能使用了。

3. vue文件里的ts配置

经过上面的配置,已经是可以使用vue的语法了,但是vue是使用ts还是不行,所以还得来配置。对之前的 ts配置进行加工。

查看配置

js 复制代码
//webpack.config.js


const config = {
 ...
 module: {
    rules: [
      {
        test: /\.ts$/, //正则,以ts结尾
        use: {
          loader: "ts-loader",
          options: {
            appendTsSuffixTo: [/\.vue$/],
          },
        },
      },
      ...
    ],
  },
html 复制代码
<template>
  <div>{{ num }}</div>
  <button @click="onCount">++</button>
</template>

<script setup lang="ts">
import { ref } from "vue";
const num = ref<number>(222);
const onCount = () => {
  num.value++;
};
</script>

这下就OK了,哈哈哈😌。

对了,加点东西,

js 复制代码
//webpack.config.js

const config = {
  ...
  stats:'errors-only',//控制台只输出错误相关的
  ...

四、支持样式、图片等

1.css配置

依赖:css-loaderstyle-loader

命令:npm i css-loader style-loader -D

所有的样式都是由css-loader统一解析,解析完之后,再交给style-loadercss-loader解析之后,会通过jshtml里动态地插入style标签,这就是style-loader的作用。

js 复制代码
//webpack.config.js

const config = {
 ...
 module: {
    rules: [
      {
        ...
        test: /\.css$/,
        use: ["style-loader", "css-loader"], //从右往左解析
      },
      ...
    ],
  },

2. scss配置

依赖:sass sass-lader

命令:npm i sass sass-loader -D

有点地方有出入了,在style里我们是会这样写scss,那在webpack里的test怎么写呢?

写成scsssass都会报错!!看一下官网 sass-loader

js 复制代码
//webpack.config.js

const config = {
 ...
 module: {
    rules: [
      {
        ...
        test: /\.s[ac]ss$/,
        use: ["style-loader", "css-loader", "sass-loader"]
      },
      ...
    ],
  },

同理,less也是这么配的。

3. postCSS配置

使用postCSS,使样式在各个浏览器兼容性问题自动配置。

依赖:postcss-loaderautoprefixer

命令:npm i postcss-loader autoprefixer -D

在项目根目录创建postcss.config.js文件。

js 复制代码
//postcss.config.js

const Autoprefixer = require("autoprefixer");

module.exports = {
  plugins: [Autoprefixer],
};

webpack.config.js里对css进行处理。

js 复制代码
//webpack.config.js

    ...
     {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"]
      },
   ...

4.图片、字体配置

依赖:url-loaderfile-loader

命令:npm i url-loader file-loader -D

其中file-loader是不需要配置的。

注:对于资源模块,其实在w5已经不需要这些loader了,有更方便的配法 资源模块

js 复制代码
    //webpack.config.js

    ...
     {
         test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
         use: [
          {
            loader: "url-loader",
            options: {
              limit: 100 * 1024,//文件小于时,会转为base64
            },
          },
        ],
      },
   ...

正常情况下,到这里就没问题了。但是但是报错,就是文件类型的问题。这时我们需要创一个声明文件image.d.ts

js 复制代码
/* images.d.ts文件 */

declare module "*.svg";
declare module "*.png";
declare module "*.jpg";
declare module "*.jpeg";
declare module "*.gif";
declare module "*.bmp";
declare module "*.tiff";

完善一下tsconfig.json

js 复制代码
  ...
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue"
  ]

!!!😫😫😫。这时候头疼的东西来了,使用img标签就能让图片展示,使用添加背景的方式就是不能,原因就是路径错误。啊这个路径错误找了好久,个把小时都搞不定,后面才是阴差阳错的搞定了。 !! 得在option对象里添加一个属性esModule:false,真的是头都麻了。

5.语法兼容配置

webpack只能兼容普通语法,高级的语法不行,所以还得配。

五、处理第三方包

1. js

这时候,项目已经是比较全了,这时候我们可以安装一些第三方库,比如momentelementUIechars等等,这时打包的话会将所有的东西都放在boundle.js里。

如果以后第三方工具越来越多,那这个bundle.js的文件就会越来越大,那就会阻塞浏览器的渲染,导致加载时间越来越长。这时我们就可以进行分包,把一些公共依赖或者第三方模块拆出来。

js 复制代码
//webpack.config.js

const config = {
  ...
   output: {
    path: path.resolve(__dirname, "dist"), //生成目录
    filename: "[name].[contenthash:8].bundle.js", //打包生成的文件名
    clean: true, //清空打包结果
  },
  ...
  
  // 优化拆分
  optimization: {
    splitChunks: {
      cacheGroups: {
        moment: {
          name: "moment", //文件名
          chunks: "all", // 不分异步同步
          test: /[\\/]node_modules[\\/]moment[\\/]/,
        },
        commons: {
          name: "commons",
          chunks: "all",
          minChunks: 2, //同个依赖被引用超过2个,就会被拆分
        },
      },
    },
  },
}

2.css

现在已经可以正常将第三方包拆分出来了,但是,我们写了css样式,这个并没有把css分出来。这时候是会通过js去动态地插入style标签,这样性能其实不是很好啊,我们是希望通过link的方式去引入,把css文件单独抽离出来。

依赖:mini-css-exract-plugin

命令:npm i mini-css-extract-plugin -D

js 复制代码
//webpack.config.js

const config = {
  ...
  plugins: [
    ...
    new MiniCssExtractPlugin(),
  ], 
  ...
  module: {
    rules: [
      ...
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"], //从右往左解析
      },
      ...
    ],
  },
}

六、打包目录

现在打包时,可以打jscss图片了,不过他们都挤在dist文件夹里,现在优化一下,让它们有自己的文件夹。

1. js

打包在js文件夹里。

js 复制代码
 output: {
    path: path.resolve(__dirname, "./dist"), //生成目录
    filename: "./js/[name].[contenthash:8].bundle.js", //打包生成的文件名
    clean: true, //清空打包结果
  },

2.css

打包在css文件夹里。

js 复制代码
 plugins: [
    new HtmlWebpackPlugin({ template: "index.html" }),
    new VueLoaderPlugin(),
    new MiniCssExtractPlugin({
      filename: "css/[name].[contenthash:8].css",
    }),
  ], 

3. 图片、字体

打包在static文件夹里。

js 复制代码
    {
        test: /\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
        use: [
          {
            loader: "url-loader",
            options: {
              outputPath: "static",
              esModule: false,
              limit: 100 * 1024,
              name: "[name].[contenthash:8].[ext]",
            },
          },
        ],
        type: "javascript/auto",
      },

这样,一个基本的vue + ts 的工程就搭建起来了🤣🤣🤣🤣。

相关推荐
吃杠碰小鸡20 分钟前
commitlint校验git提交信息
前端
虾球xz1 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇1 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒1 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员1 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐1 小时前
前端图像处理(一)
前端
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒1 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪2 小时前
AJAX的基本使用
前端·javascript·ajax
力透键背2 小时前
display: none和visibility: hidden的区别
开发语言·前端·javascript