1. webpack打包原理:
把所有的依赖打包成bundle.js
文件,通过代码分割成单元片段并按需加载。
2. bundle,chunk,module分别是什么:
bundle
: 由webpack打包出来的文件;
chunk
:webpack在进行进行模块依赖分析的时候由代码分割而出来的代码块;
module
:开发中的单个模块。
3. 什么是loader,什么是plugin
loader
用于加载一些资源文件,由于webpack只能打包符合common.js
规范的js文件,而对于css样式文件,html网页结构文件,img静态资源无法进行加载打包,这是就需要使用对应的loader将资源转化进而进行加载打包。
plugin
用来扩展webpack的功能,使webpack更加强大,不同于loader,plugin的功能更加丰富多样,比如对代码进行压缩打包,优化,比仅仅局限与对资源的加载。
UglifyJsPlugin
: 压缩代码HotModuleReplacementPlugin
: 自动刷新HtmlWebpackPlugin
依据一个简单的index.html模版,生成一个自动引用你打包后的js文件的新index.htmlExtractTextWebpackPlugin
它会将入口中引用css文件,都打包都独立的css文件中,而不是内嵌在js打包文件中Tree-shaking
指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码- 在webpack中Tree-shaking是通过
uglifySPlugin
来Tree-shaking,css需要使用Purify-CSS
4. 有哪些常见的loader,plugin?他们都是用来解决什么问题的?
-
常见的Loader:
file-loader
: 把文件输出待一个文件夹中,在代码中同归相对url去引用输出的文件;url-loader
: 和file-loader相似,但是可以使用base64的方式把文件注入到代码中,可以减小文件的大小;image-loader
: 加载并压缩图片文件;babel-loader
: 将ES6转换成ES5;css-loader
: 加载css,支持模块化、压缩、文件导入等特性;style-loader
: 把css,代码注入到js中,通过操作DOM加载css;eslint-loader
: 通过eslint检查代码格式,使代码整体变得很规范;source-map-loader
: 加载额外的Source Map文件,以方便调试。 -
常用的plugin:
define-plugin
:定义环境变量;commons-chunk-plugin
:提取公共的代码;uglifyjs-webpack-plugin
:通过UglifyES压缩ES6代码。
5. webpack-dev-server和HTTP服务器有什么区别
webpack-dev-server使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,相比传统的HTTP服务对开发更加简单高效。
6. 什么是模块热更新
官方解释:使得应用在运行状态下,不重载刷新就能更新、增加、移除模块的机制
这是webpack的一个功能,可以使代码修改后不用刷新页面就自动更新,提升开发效率
通过配置devServer的hot为true和hotModuleReplacement插件完成。
-
热更新原理:
1.启动dev-server,webpack开始构建,在编译期间会向 entry 文件注入热更新代码;
2.Client 首次打开后,Server 和 Client 基于Socket建立通讯渠道;
3.修改文件,Server 端监听文件发送变动,webpack开始编译,直到编译完成会触发"Done"事件;
4.Server通过socket 发送消息告知 Client;
5.Client根据Server的消息(hash值和state状态),通过发送ajax请求到 Server端获取新的JS模块
7.Client获取到新的JS模块后,会更新 modules tree并替换掉现有的模块;
8.最后调用 module.hot.accept() 完成热更新。
7. webpack的入口文件怎么配置?多个入口怎么分割?
webpack.config.js:
const path = require('path');
module.exports = {
// 入口文件的配置
entry: {
entry: './src/entry.js',
entry2: './src/entry2.js',
},
// 出口文件的配置
output: {
// 出口的路径
path: path.resolve(__dirname, 'dist'),
// 输出的文件名称
filename: '[name].js'
},
// 模块化
module: [
],
// 插件
plugins:[
],
// webpack开发服务功能
devServer: {
}
}
8. Webpack构建流程:
Webpack在启动后,会从Entry开始,递归解析Entry依赖的所有Module,每找到一个Module,就会根据Module.rules里配置的Loader规则进行相应的转换处理,对Module进行转换后,再解析出当前Module依赖的Module,这些Module会以Entry为单位进行分组,即为一个Chunk。因此一个Chunk,就是一个Entry及其所有依赖的Module合并的结果。最后Webpack会将所有的Chunk转换成文件输出Output。在整个构建流程中,Webpack会在恰当的时机执行Plugin里定义的逻辑,从而完成Plugin插件的优化任务。
基础配置:参考官方配置示例
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: ['babel-polyfill','./src/main.js']
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
// 排除模块,下面的模块不会编译到 webpack 打包后的文件中
externals: {
"vue": "Vue",
"vuex": "Vuex",
"vue-router": "VueRouter",
"lodash": "_",
"echarts": "echarts"
},
plugins: [
// 全局模块对象
new webpack.ProvidePlugin({
"Vue": "vue",
"Vuex": "vuex",
"VueRouter": "vue-router",
"_": "lodash",
"echarts": "echarts"
})
],
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.scss/,
loader: ['style','css','scss']
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
配置项说明:
entry
: 指定了模块的入口,它让源文件加入构建流程中被webpack控制。
output
: 配置如何输出最终的代码结果。
module
: 配置各种类型的模块的处理规则和解析策略。
resolve
: 配置webpack寻找模块的规则。
plugin
: 配置扩展插件,扩展webpack的更多功能。
devServer
: 配置DevServer,实现本地HTTP服务、模块热替换、source map调试等。
9. webpack的优势,与gulp的区别
- 优势:
- webpack是以common.js的形式来书写脚本,对AMD/CMD也支持,方便对旧项目进行代码迁徙;
- 开发便捷更替代部分grunt/gulp的工作,如:打包、压缩混淆、图片转换base64;
- 能被模块化的比仅仅局限与js;
- 扩展性强,插件机制完善。
-
与gulp的区别:
webpack是一个模块打包器,基于入口的,强调的是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源都看成是模块,通过loader和plugin对资源进行处理。
grunt和gulp是基于任务和流,gulp是一个前端自动化构建工具,强调的是前端开发的工作流程,可以通过配置一系列的task,task处理的事情(如代码压缩,合并,编译以及浏览器实时更新等)。然后定义这些执行顺序,来让glup执行这些task,从而构建项目的整个开发流程。自动化构建工具并不能把所有的模块打包到一起,也不能构建不同模块之间的依赖关系。