webpack需要牢记于心的基本概念

1.对webpack的了解

本质上,webpack是一个现代JS应用程序的静态模块打包器(module bundler),将项目作为一个整体,通过一个给定的主文件,webpack将从这个文件找到的项目的所有依赖文件,使用loader处理它们,最后打包成一个或多个浏览器可识别的js文件。 核心概念: 入口(entry):入口起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部依赖的开始。可以在webpack中配置entry属性,来指定一个入口起点或多个入口起点。

module.exports {
    entry:'./path/project/entry/file.js'
};

输出(output):output属性告诉webpack在哪里输出它所创建的bundles,以及如何命名这些文件,默认值为./dist 加载器(loader):让webpack能够去处理那些非JavaScript文件,因为webpack自身只理解JavaScript 插件(plugins):loader被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量。 模式(mode):通过选择development(开发)或production(生产),来设置mode参数,可以启用webpack内置的优化。

module.exports = {
    mode:'production'
};

2.webpack里面的webpack.config.js怎么配置

let webpack = require('webpack');

module.exports = {
    entry:'./entry.js',// 入口文件

    output: {
        // node.js中__dirname变量获取当前模块文件所在目录的完整绝对路径
        path:__dirname,     // 输出位置
        filename:'build.js' // 输出文件
    }

    module: {
        // 模块加载相关,定义在module.loaders中,通过正则匹配不同后缀的文件名,然后给它们定义不同的加载器;
        // 比如说给less文件定义串联的三个加载器(!用来定义级联关系);
        rules:[
            {
                test:/\.css$/, //支持正则
                loader:'style-loader ! css-loader'  // 从右往左执行
            }
        ]
    },

    devServer: { // 配置服务
        hot:true, // 启用热模块替换
        inline: true // 此模式支持热模块替换:热模块替换的好处是只替换更新的部分,而不是页面重载
    },

    resolve:{ // 其他解决方案配置
        extentions:['','.js','.json','.css','.scss']
    },

    plugins: [ // 插件,注意这里是个数组
        new webpack.BannerPlugin('the file is create by jerrychane')
    ]
}

3.webpack本地开发怎么解决跨域的

下载webpack-dev-server插件;配置webpack.config.js文件

// webpack.config.js
var WebpackDevServer = require('webpack-dev-server');

module.exports = {
    ...
    devServer: {
        port: '8088', // 设置端口号
        proxy: { // 代理设置
            '/api': {
                target: 'http://localhost:80/index.php', // 目标代理
                pathRewrite:{'^api' : ''},// 重写路径
                source: false, // 是否接受运行在HTTPS上
            }
        } 
   }
}

4.如何配置多个入口文件

entry: {
    home: resolve(__dirname, 'src/home/index.js'),
    about: resolve(__dirname,'src/about/index.js')
}

5.webpack与grunt、gulp的区别

(1)三者都是前端构建工具; (2)grunt和gulp是基于任务和流的。找到一个或一类文件,对其做一系列链式操作,更新流上的数据,整个链式操作构成了一个任务,多个任务就构成了整个web的构建流程。 (3)webpack是基于入口的。webpack会自动地递归解析入口所需要加载的所有资源文件,然后用不同的loader来处理不同的文件,用plugin来扩展webpack功能。 (4)webpack与前者最大的不同就是支持代码分割,模块化(AMD,CommonsJS,ES6),全局分析。

6.有哪些常见的loader,对应解决哪些问题

css-loader: 加载css,支持模块化、压缩、文件导入等特性; style-loader: 把CSS文件注入到JavaScript中,通过DOM操作去加载CSS; slint-loader:通过Slint检查JavaScript代码; babel-loader: 把ES6转换成ES5; file-loader: 把文件输出到一个文件夹中,在代码中通过相对URL去引用输出的文件; url-loader:和file-loader类似,但能在文件很小的情况下以base64的方式把文件内容注入到代码中去;

7.有哪些常见的Plugin,他们是解决什么问题的

define-plugin:定义环境变量; SplitChunkPlugin:提取公共代码; MiniCssExtractPlugin:单独生成css文件; HtmlWepackPlugin:生成html文件;

8.loader和plugin的不同

loader(加载器):webpack将一切文件视为模块,但是webpack原生只能解析js文件,而loader则让webpack拥有了加载和解析非JavaScript文件的能力。loader在module.rules中配置,作为模块的解析规则而存在,类型为数组。 plugin(插件):扩展webpack的功能,让webpack具有更多的灵活性;在plugins中单独配置,类型为数组,每一项是一个plugin的实例,参数通过构造函数传入。

9.webpack的构建流程

(1)初始化参数:从配置文件和shell语句中读取与合并参数,得出最终的参数; (2)开始编译:用上一步得到的参数初始化compiler对象,加载所有配置的插件,执行对象的run方法开始执行编译; (3)确定入口:根据配置中的entry找出所有的入口文件; (4)编译模块:从入口文件出发,调用所有配置的loader文件模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理; (5)完成模块编译:在经过第(4)步使用loader翻译完所有模块后,得到每个模块被翻译后的最终内容以及它们之间的依赖关系; (6)输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表,这一步是可以修改输出文件内容的最后机会; (7)输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把内容写入到文件系统; 在以上过程中,webpack会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用webpack提供的API改变webpack的运行结果。

10.编写loader或plugin的思路

编写loader时要遵循单一原则,每个loader只做一件’转译’工作。每个loader拿到的是源文件的内容(source),可以通过返回值的方式将处理后的内容输出,也可以调用this.callback()方法,将内容返回给webpack。还可以通过this.async()生成一个callback函数,再用这’callback’将处理后的内容输出出去。 相对于loader,plugin的编写就灵活了很多。webpack在运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结构。

11.webpack的热更新是如何做到的,说明其原理

当对代码进行修改并保存后,webpack将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换旧的模块,这样在不刷新浏览器的前提下就能够对应用进行更新。主要原理是:在启动webpack-dev-server时,sockjs在服务端和浏览器端建立了一个webSocket的长连接,webpack会将sockjs client端的代码打包到输出的html中。

12.如何利用webpack来优化前端性能

(1)压缩代码:删除多余代码、注释、简化代码的写法等方式 (2)利用CDN加速:在构建过程中将引用的静态资源路径修改为CDN上对应的路径 (3)删除死代码(Tree Shaking):将代码中永远不会走到的片段删除掉 (4)优化图片:对于小图可以使用base64的方式写入到文件中 (5)按路由拆分代码,实施按需加载,提取公共代码 (6)给打包出来的文件名添加hash(哈希),实现浏览器缓存文件

13.如何提高wepback的构建速度

(1)利用alias:配置别名可以加快webpack查找模块的速度; (2)插件CleanWebPackPlugin:清除每次打包时dist目录下的旧版文件; (3)文件压缩:webpack4只要在生产模式(mode:production)下,代码就会自动压缩; (4)DllPlugin插件打包第三方类库:对于很长一段时间基本不会再更新的第三方类库,可以使用DllPlugin动态链接库插件,其原理是把网页依赖的基础模块抽离出来打包到dll文件中,当需要导入的模块存在于某个dll中时,这个模块不再被打包,而是去dll中获取; (5)利用happypack并发执行任务;

14.webpack配置单页面应用与配置多页面应用

单页面应用可以理解为webpack的标准模式,直接在entry中指定单页应用的入口即可; 多页面应用,可以使用webpack的AutoWebPlugin来完成简单自动化的构建,但前提是项目的目录结构必须遵循预设的规范。

15.bundle/chunk/module是什么

bundle是webpack打包出来的文件; chunk是webpack进行模块的依赖分析时,分割出来的代码块; module是开发中的单个模块。