← 返回首页
建构工具和脚手架
发表时间:2023-12-23 17:15:29
建构工具和脚手架

建构工具和脚手架。

1.构建工具

简单说构建工具就是来完成工程转换的,把开发的工程结构转换为运行时的工程结构。构建工具要完成转换必须要明确以下三个问题。

  1. 哪种工程更适合开发和维护。
  2. 哪种工程更适合运行时。
  3. 如何进行转换(打包)

常见的构建工具有:webpack,vite,rollup,esbulid,grunt等等。这么多构建工具的出现就是因为对上面三个问题的理解不一致造成的。但是是这么多构建工具中用的最多的就是webpack,所以说webpack是必须要掌握的。

webpack是如何理解哪种工程更适合开发和维护呢?简单一句话,就是一切皆模块! webpack又是如何理解哪种工程更适合运行时环境呢?就是传统工程。比如:js、css、images这种目录结构。 webpack又是如何转换呢?我们看下面这个图。

简单说就是通过入口js去寻找依赖关系,然后打包合并。

2.理解webpack

1).如何打包

首先webpack的入口是可以配置的。比如:在webpack.config.js中

module.exports = {
    entry: './src/main.js',
};

webpack分析这个依赖关系,并不是运行代码。而是把整个代码看成是一个字符串。然后把字符串分解为AST(抽象语法树),通过这个抽象语法树找到所有的导入语句。而且webpack支持CommonJs和ESM。也就是说你源代码里写的所有导入语句都是写给webpack看的。webpack打包之后再浏览器看来是不存在任何导入模块的。

除此之外webpack还要解决模块是如何查找的?比如:你使用import导入的是一个文件夹,那么webpack就会默认去寻找文件夹里的index.js文件。

import './cover';  //默认就去寻找cover目录下的index.js

再比如说:你使用import导入不是以./或者../开头,就会按照node模块的查找规则。


//首先查找到node_modules目录,然后查找package.json里的main属性,定义的入口。
import $ from 'jquery';  //默认去寻找node_modules下的jquery模块。

这些具体的查找规则是很繁琐的。比如:导入的时候有可能会使用别名。

import {getMovie} from '@/api/movie';

这个别名@是可以配置的。比如:在webpack.config.js

 configureWebpack: {
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
        components: '@/components'
      }
    }
  },

2).开发服务器

使用下面命令,可以运行开发服务器。类似VSCode里的live server。

npm run serve

这样就不用先打包,再单独打开打包后的工程运行项目了。内部实现原理是通过webpack-dev-server这个插件去启动express。并且会帮你自动执行npm run build进行打包,把打包结果保存在内存中。然后启动浏览器去访问项目,其运行原理如下图所示:

webpack会监听代码内容的改变,一旦代码内容被修改,就会触发重新打包,打包的结果会保存在内存里面,再通过websocket触发浏览器刷新,重新发送请求。

这个动态刷新有两种模式,一种是刷新整个浏览器,另一种称为HMR。

3).文件指纹

我们发现webpack打包之后的js文件都带有一个hash值。如下图所示:

源文件的内容的修改就会影响文件指纹,这个道理和MD5一样,是一种摘要算法。如果不使用文件指纹,会出现浏览器缓存问题。因为浏览器会优先使用缓存里的结果,会造成无法获取更新后的结果。

4).css modules

我们发现打包后的css文件里的类名和源代码里的类名不一致,打包后的css里的类名会出现各种奇奇怪怪的字符。这里我们就可以使用css modules实现获取源码的类名和打包后的类名的对应关系。

/*打包之后的css类名。*/
.mynavbar_logo_div[data-v-769330d7] {
    float: left;
    width: 120px;
    height: 60px;
    vertical-align: middle;
    color: #fff
}

那么我们在源码中如何获取打包之后的css类名呢?我们可以导入index.module.less动态获取。

import styles from './index.module.less';

..
container = $('<div>').addClass(styles.mynavbar_logo_div).appendTo('#app');

5).源码地图

我们可以在webpack.config.js或者vue.config.js里关闭源码地图。

module.exports = defineConfig({
    transpileDependencies: true,
    lintOnSave: false,//禁用eslint严格的语法检查...
    // 生产环境下关闭源码地图,即不生产对应的map文件,减小打包结果的体积
    productionSourceMap: false,
    ...
})

但是一旦关闭了源码地图,在生成环境下不利于断点调试,因为源码地图的作用就是把运行时的代码和源代码一一对应起来。这个对应关系就是源码地图。总之源码地图好处就是方便调试的。

小结: webpack不仅仅是一个技术,它是集成了很多很多的技术。通过它的两个扩展点:1.loader 2.plugin, 可以把其它各种各样的工具融入进来。

2.脚手架

简单说脚手架就是帮我们来搭建工程的。常见的脚手架工具有以下:

脚手架的两个作用:

  1. 提供界面交互
  2. 提供一套工程模板

实际工作时候是需要有自己写脚手架的能力。