![f773caac44d8e1ed2d301f8422d9b171.png](https://i-blog.csdnimg.cn/blog_migrate/d99ff0cee70a6aefa070d1f6f7423bee.jpeg)
上次在公司写个项目,把前后端一起做了,前端用 vue(我们用的 vue,以下内容跟 vue 没关系) 后端用 node
然后把代码按前后端分开,前端放在 src
下面,后端放在 app 下面
大概这个样子
├── bin
│ └── start.js 启动入口文件
├── app
│ ├── business
│ │ ├──
│ │ ├──
│ │ └──
│ └── index.js 入口文件
├── lib 服务端打包文件
├── src 前端源码
└── dist 前端打包文件
做前端路由的时候,不是可以通过一些方式做路由拆分么
以前都是用require.ensure
, 后来大家又开始用 import()
我们的项目模板都比较老,用的还是vue-cli@2.X
,用习惯了,就懒得改了
那么我们的项目配置下来就跟标准的模板差不多(反正改动的地方也不能拿出来给你们看不是~~)
按理说照着官方的示例应该就可以,但是出问题了
因为我们的项目结构是app
,src
, 所以我会将所有前端代码都放在src
下面,包括一些第三方库--没法打包的那种
这里插一点小知识, 我们项目用了uglify
,而这个插件,只支持es5
,像es6
的箭头函数,方法简写什么的,通通不支持
第三方库一般是通过一些比较特殊的方式来按需加载或者直接写在html
里头,不会被业务代码直接require/import
然后问题出现了,我们在路由里头用了import()
,打包就报错,报错的位置是我们的第三方库(说是第三方,其实是其他组开发的东西)
一开始我就不理解,找了好久,没有任何地方引用到这里,为什么会来打包它,打包也就算了,还给我报错,,,
后来发现,如果用require([])
或者require.ensure()
这种,就不会有问题
然后我就开始想这两者的区别
我不知道有没有人这么写过代码:
const moduleName = '' //模块路径
const asyncComponent = resolve => require([moduleName], resolve)
这个代码,看着好像没什么问题,但是 webpack 会报错的,说这里的moduleName
是个变量,不允许,只能是个字符串, webpack 为了解决这个问题,还提供了一个 require.context
的语法。
所以为什么是这个样子的?
- 首先 webpack 的职责是打包,做依赖分析,而其他的功能,比如能让万物皆为模块,这个是通过插件实现的,并不是 webpack 自身的功能
- 那么它怎么做到来分析你的模块依赖的?
就是通过require
这个函数, 其实在前端代码中用到的require
, 跟服务端的require
完全不是一回事, 前端代码的require
是 webpack 提供的,有点像requirejs/seajs
,但是它规定了这个方法只能接受纯粹的字符串,表达式是不可以的,然后通过入口文件开始,所有的依赖都是纯粹的字符串,就能很明确的计算出来一共有多少依赖,一个不多,一个不少 - 所以为什么用
import()
这个语法就报错了呢? > 因为import()
是es6
语法, 这个本身的含义就是dynamic import
,叫做动态加载, 就是在编码的时候,你并不知道需要引入什么, 这个是es
规范, webpack 并没有尝试像修改require
那样,也提供一个自己的动态import
语法(也没有必要,一定要用的话,以前的方案就可以)
require 与 import()
既然import()
这么动态,根本没办法知道运行时到底是什么,那么 webpack 怎么打包?
答案是把所有内容都打一遍
这是为什么我的项目中,使用require([])
就没问题, 用import()
就报错的原因,我把所有的内容都放到了 src
下面, webpack 配置也指定了这里,然后它就尝试把 src
下所有文件都打包一下,然后碰到了其他组的代码,就挂了
所以归根到底,这玩意儿有啥用?
理论上来说,如果你的所有模块都能被打包,这东西于你来说,区分和不区分,效果上没啥区别,除了增加一点成果物体积之外,也没什么副作用
如果不使用import()
语法的话,也一点关系都没有,反正所有的依赖都是确定的,也就不会有问题。
如果使用 import()
首先,如果不是所有模块都能打包,那么这部分内容需要放到src
外面去,不然会报错;
然后,如果有一部分内容,虽然也能被打包,但是并不会直接被代码引用,这种也需要放到src
外面去, 一来加快打包速度,二来减小成果物体积--因为 webpack 打包会拷一遍,然后你为了能用,一般也会加一个copyplugin
再copy
一遍
简单来说,就是需要区分一下哪些内容需要被打包,哪些不能被打包。