webpack安装
- 安装本地webpack
- yarn install -y
- yarn add webpack webpack-cli -D
- 没有 yarn 就换成 cnpm
webpack可以进行0配置
- 打包工具 -> 输出后的结果
- npx webpack : 这是webpack5.2支持的打包,默认查找node_modules/bin/webpack.cmd(针对window电脑),一般会node_modules/webpack/bin/webpack.js
- 打包(默认支持js的模块化)
手动配置webpack
- 默认配置文件的名字 webpack.config.js或者webpackfile.js。因为node_modules/webpack-cli/bin/config-yargs.js中进行了一个配置。
- 打包后结果是匿名自执行函数,参数是key-value形式,key->模块的路径,value->value函数。
- 打包文件:定义了缓存,配置和实现了require方法。这里我感觉是__webpack_require__实现了递归调用
- 功能:把解析的所有模块变成对象,通过对应入口去加载各种模块,实现递归的依赖关系,通过入口来运行所有的文件。
- 可以手动指定运行的配置文件,例如 npx webpack --config webpack.config.my.js
- 或者在package.json中配置脚本,scripts选项
webpack运行在服务端localhost或者IP
- cnpm install webpack-dev-server -D
- npx webpack-dev-server 不会真实打包文件,仅生成内存中的打包。
样式处理
- module: { rules: [{test:/.css$/,use:[{loader:‘style-loader’,options:{}},‘css-loader’,‘less-loader’]},{}] } 规则
- css-loader 接续 @import这种语法的
- style-loader 把css插入到head标签中
- loader的特点 希望单一
- loader的用法 字符串只用一个loader
- 多个loader需要 []
- loader的顺序 默认是从右向左执行,从上到下执行
- loader还可以写成 对象方式
- 自动添加css前缀 yarn add posscss-loader autoprefixer -D
- 插件optimize-css-assets-webpack-plugin 优化压缩css代码
转ES6语法
- yarn add babel-loader @babel/core @babel/preset-env
- 用babel-loader需要把es6转为es5
全局变量引入问题
- expose-loader 暴露全局的loader,即内联的loader
- (1)js文件中的用法,例 import $ from 'expose-loader? ! j q u e r y ′ , 就 可 以 使 用 w i n d o w . !jquery' ,就可以使用window. !jquery′,就可以使用window.了
- (2)配置webpack.config.js: {test:require.resolve(‘jquery’),use:‘expose-loader?$’}
- (3)新增加属性: externals:{ jquery: ‘$’} 引入但是不会打包,cdn
- 分类:pre 前面执行的loader; normal 普通的loader; 内联loader; 后置postloader
- 插件:webpack.ProvidePlugin({KaTeX parse error: Expected 'EOF', got '}' at position 10: :'jquery'}̲) //在每个模块中都注入
- 总结: 1.expose-loader暴露到window上 2.providePlugin 给每个人提供一个$ 3.引入不打包
图片处理
- (1)在js中创建图片来引入
- (2)在css引入,如background
- (3)
html-withimg-loader {test:/.html/,use:‘html-withimg-loader’}
打包文件分类
打包多页应用
- entry: { home:’./src/index.js’,other:’./src/other.js’ }
- output: { filename: ‘[name].[hash].js’, path: path.resolve(__dirname, ‘dist’) } //[name] home,other
- html-webpack-plugin生成html,并且chunks属性自动把js引入进去
配置source-map
- devtool:‘source-map’ 增加映射文件,可以帮我们调试源代码;源码映射,会单独生成一个sourcemap文件,出错了会标识当前报错到列和行,大而全。
- devtool:‘eval-source-map’ 不会产生单独的文件,但是可以显示行和列
- devtool:‘cheap-module-source-map’ 不会产生列,但是是一个单独的映射文件,产生后你可以保留起来用于调试
- devtool:‘cheap-module-eval-source-map’ 不会产生文件,集成在打包后的文件中,不产生列
watch用法
- watch:true, watchOptions:{ poll:1000, aggreatement:500, ignored:/node_modules/ }
- 监控的选项:每秒向我问1000次,防抖,不需要监控的文件
webpack小插件应用
- cleanWebpackPlugin(’./dist’) 清空某个文件夹
- copyWebpackPlugin([{from:‘doc’,to:’./’}]) 把doc文件夹下的所有文件拷贝到dist文件夹下
- bannerPlugin
- 前两个是第三方模块,第三个是内置的
webpack跨域问题
- (1)devServer:{ proxy:{’/api’:{target:‘http://localhost:3000’,pathRewrite:{’/api’:’’}}} }
- (2)前端只想单纯来模拟数据:devServer:{ before(app){调node接口} }
- (3)有服务端,不用代理来处理,在服务端启动webpack,端口用服务端口,前端和服务端启动在一个端口上
resolve属性的配置
- modules:[path.resolve(‘node_modules’)]解析第三方模块包
- extensions:[’.js’,’.css’,’.json’] 依次解析js,css,json
- mainFields:[‘style’,‘main’]
- mainFiles:[] 入口文件的名字
- alias:{bttostrap:‘bootstrap/dist/css/bootstrap.css’} 别名
定义环境变量
- 在plugins中配置new webpack.DefinePlugin({Dev:"‘dev’",a:JSON.stringify(‘a’)},flag:‘true’)
区分不同环境
- 新建两个文件webpack.prod.js和webpack.dev.js
- let {smart} = require(‘webpack-merge’)
- smart(base,{})
---------webpack优化系列 在module属性中配置----------------
noParse
- module:{noParse:/jquery/,rules:[]} 不去解析jquery中的依赖库
IgnorePlugin
- let webpack = require(‘webpack’)
- 栗子: plugins:[new webpack.IgnorePlugin(/./locale/,/moment/)]
dllPlugin
- 在output中配置library:'ab’和libraryTarget:‘var’,前者指定返回值由ab变量接收,后者指定是否输出
- 在plugins中配置 new webpack.DllPlugin({name:‘填入library属性值’,path:path.resolve(__dirname,‘dist’,‘manifest.json’)})
- 引用动态链接库: new webpack.DllReferencePlugin({manifest: path.resolve()})
happypack: webpack实现多线程打包
- yarn add happypack 以前module:rules 匹配js用babel-loader,现在用happypack
- rules:[{test:/.js$/,use:‘happypack/loader?id=js’}]
- plugins:[new happypack({id:‘js’,use:[{loader:‘babel-loader’,options:{presets:[’@babel/preset-env’,’@babel/preset-react’]}}]})]
webpack自带优化
- tree-shaking把没用到都代码自动删除 import在生产环境下,会自动删掉没用的代码。对象名.default.方法名进行调用,因为es6 模块会把结果放到default上。
- scope hosting: 作用域提升。在webpack中可自动省略一些可以简化的代码
抽离公共代码
- optimization:{splitChunks:{cacheGroups:{common:{},vendor:{}}}}