参考文章: https://www.jianshu.com/p/91a4214b913b
https://segmentfault.com/a/1190000014251654?utm_source=tag-newest
https://www.jianshu.com/p/cb0db034cb17
https://blog.csdn.net/w178191520/article/details/85932849
https://blog.csdn.net/qq_39343308/article/details/86159668
1.卸载全局的 webpack
npm uninstall webpack webpack-cli -g
其中安装webpack-cli 是可以让webpack在命令行执行的。在webpack 4.0 中需要安装。
2 局部安装webpack
npm install webpack webpack-cli -D
3. 具体安装某个版本:
npm install webpack@4.16.5 webpack-cli -D
附,webpack安装版本:
{ "name": "lesson", "sideEffects": false, "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.2.0", "@babel/plugin-transform-runtime": "^7.2.0", "@babel/preset-env": "^7.2.0", "@babel/preset-react": "^7.0.0", "autoprefixer": "^9.3.1", "babel-loader": "^8.0.4", "clean-webpack-plugin": "^1.0.0", "css-loader": "^1.0.1", "express": "^4.16.4", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "node-sass": "^4.10.0", "postcss-loader": "^3.0.0", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "url-loader": "^1.1.2", "webpack-cli": "^3.1.2", "webpack-dev-middleware": "^3.4.0", "webpack-dev-server": "^3.1.10" }, "dependencies": { "@babel/polyfill": "^7.0.0", "@babel/runtime": "^7.2.0", "@babel/runtime-corejs2": "^7.2.0", "react": "^16.6.3", "react-dom": "^16.6.3", "webpack": "^4.25.1" } }
=================================
首先新建最基本的构造:
执行 npm init 生成的配置文件
{ "name": "webpack", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "webpack" }, "author": "zhenyulei", "license": "ISC", "devDependencies": { "html-webpack-plugin": "^3.2.0", "webpack": "^4.16.5", "webpack-cli": "^3.3.1", } }
webpack.config.js文件:
const webpack = require ('webpack'); const path = require ('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { main:'./src/index.js' }, output:{ filename:'[name].js', path:path.resolve(__dirname,'dist') }, plugins:[ new HtmlWebpackPlugin({ template:'./src/index.html' }) ] }
=========================================
4. 样式css配置
先安装 'style-loader','css-loader','sass-loader,'node-sass'
module:{ rules:[{ test:/.css$/ , use:['style-loader','css-loader','sass-loader'] }] }
sass-lode处理scss文件, css-loader 处理css文件之间 import的引用;style-loader 会把css-loader转换成的css挂在到html生成的header部分;使用sass-loader 还要安装 node-loader
5. 自动添加css前缀 npm i postcss-loader autoprefixer -D 注意的是 这只是针对直接引用的css样式,而不能给 css中 在 @import进来的css,原因见6;
module:{ rules:[{ test:/.scss$/ , use:[ 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader' ] }] }
然后在postcss.config.js 中定义autoprefixer插件
module.exports = { plugins:[ require('autoprefixer')({ "browsers": [ "defaults", "not ie < 11", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions" ] }) ] }
如果打包编译报警告:
则将postcss文件中 browsers 改为:"overrideBrowserslist"
6 如果scss中引入其他的scss,如 @import './index.scss'
这种情况下,如果不做设置,index.scss就会从css-loader开始执行,所以要在下面设置 css-loader的参数:每次要执行几个路径:
module:{ rules:[{ test:/.css$/ , use:[ 'style-loader', { loader:'css-loader', //css-loader如果要增加下面的配置项,则写成对象形式。 options:{ importLoaders:2, //表示在css中 使用import引入的css文件,也要执行下面两个loader modules:true //css模块化打包,也就是哪个页面引入了该css,则对哪个页面有效,避免影响其他的文件(后续发现,设置了该值样式不在生效) } }, 'postcss-loader', //这里注意postcss和sass的loader顺序 'sass-loader' //先用sass编译成css,再用postcss ] }] }
7 加载图片loader
module:{
rules:[{ //有多个规则,所以需要使用数组
test:/.(jpg|png|gif)$/, //匹配后缀文件
use:{
loader:'file-loader', //使用file-loader编译文件
options:{
name:'[name]_[hash].[ext]', //输出名字其中[ext]是后缀名称
outputPath:'images/', //图片的输出路径,指的是输出文件夹的 比如dist文件夹
}
}
}]
}
8. 使用url-loader 可以把小图片转成base64,然后放在打包的js文件中。他的功能比file-loader 功能更全! file-loader则是打包成单独的文件
module:{
rules:[{ //有多个规则,所以需要使用数组
test:/.(jpg|png|gif)$/, //匹配后缀文件
use:{
loader:'url-loader', //使用url-loader编译文件
options:{
name:'[name]_[hash].[ext]', //输出名字其中[ext]是后缀名称
outputPath:'images/', //图片的输出路径
limt:2048, //大小限制,比2048小的图片转成base64,大的图放在outputPath路径下
}
}
}]
}
9 根据阿里巴巴字体库( https://www.iconfont.cn/ )下载icon字体(先添加购物车,再下载代码),保存后缀为.eot,.svg,.ttf , .woff的文件,放在项目的font文件夹下;
复制下载的 iconfont.css文件中所有代码,并修改src'的路径
@font-face {font-family: "iconfont"; src: url('./iconfont.eot?t=1554433240017'); /* IE9 */ src: url('./iconfont.eot?t=1554433240017#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), url('./iconfont.woff?t=1554433240017') format('woff'), url('./iconfont.ttf?t=1554433240017') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('./iconfont.svg?t=1554433240017#iconfont') format('svg'); /* iOS 4.1- */ }
放入自己的font.css文件中
使用方法,在html中 增加必须的类名:
import './font.css' //引入字体文件的css
<div class="iconfont .icon-zhaoxiangji">abc</div>
由于webpack无法识别引入的字体文件后缀,所以要在配置文件中使用file-loader进行对字体的编译,目的是把这些文件从font文件夹下放在dist文件夹下:
{ test:/.(eot|ttf|svg)$/, use:{ loader:'file-loader' } }
并且去掉css的模块化
10 使用插件:使用 npm install html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin'); plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html' //使用该插件,可以在打包结束后,根据配置的模板, //生成html文件,并且把配置的output中的js文件引入html }) ],
clean-webpack-plugin 清除dist文件夹的内容,详见:
webpack 4.0 中 clean-webpack-plugin 的使用
const CleanWebpackPlugin = require('clean-webpack-plugin'); //清除dist文件夹的内容 plugins: [ new HtmlWebpackPlugin({ template: 'src/index.html' // 在打包之后运行 }), new CleanWebpackPlugin(),// 在打包之前运行 ],
PS: 需要修改文件,执行 npm run build之后才会生成新的打包js文件
2: 如果打包 报这个错误 CleanWebpackPlugin is not a constructor---记得改成:
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
11
module.exports = { entry: { main: './src/index.js', //多个入口文件 sub: './src/sub.js', }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') //自动生成多个出口js文件 } }
如果想让生成的html文件,引入的js文件前面自动加前缀路径:
output: { publicPath:'http://cdn.com.cn' //文件路径前缀 filename: '[name].js', path: path.resolve(__dirname, 'dist') //自动生成多个出口js文件 }
12 sourceMap
现在已经知道 dist目录下的 main.js 文件96行出错了,
sourceMap 它是一个映射关系,知道dist目录下 main.js 文件 96 行
实际上对应的是 src 目录下 index.js 文件中的第一行
devtool:'source-map' 这样设置,会在生成的文件中生成对应的map文件,记录对应关系
devtool:'inline-source-map' 会被打包到 生成的js文件中。
devtool:'cheap-inline-source-map' //cheap 只映射到哪一行 而不需要定位到那一列,并且只会映射编写的index.js 和 生成的bundle.js文件。不会管loader等其他的映射
devtool:'cheap-module-source-map' //module 还要管一些loader下的文件
实际用的过程中建议用:
devtool:'cheap-module-eval-source-map' //本地开发 eval打包快 但是提示不全面 devtool:'cheap-module-source-map' //线上提示
13 webapck-dev-server 要安装,他可以自动刷新页面,更新修改的代码。
配置文件中: "start":"webapck-dev-server"
devServer: { contentBase: './dist', //服务器使用的地址 open: true, // 设置为true时 自动打开浏览器,且由于服务器的作用,打开浏览器的地址是 http协议,否则单独打开html文件的协议是file://,这样无法使用ajax请求 port: 8080, //开启的服务器端口
proxy:{ //在这里做的配置代理,访问本地的/api 接口 都会跑到 代理的网址上去
'/api' : 'http://localhost:8000'
}
},
14 开启HMR热更新模式:即如果你更新了代码,页面不会刷新,只是修改你更改的部分,这样会保持页面原来的操作态;
1 ) 首先,设置devserver的 open
devServer: { contentBase: './dist', open: true, port: 8080, hot: true //这里
},
2) 然后使用webpack自带的热更新插件,要先引入webpack
const webpack = require('webpack'); plugins: [ new webpack.HotModuleReplacementPlugin() ]
15 上面修改css生效了 但是对于js 文件修改后 页面没有更新,看下面代码:
也就是每次更新 都要删掉 之前对应的 代码 在更新,
之所以css和vue,react等没有这样去做 是因为 使用的 scss-loader vue-loader react-loader 等loader已经帮我们内置了这个功能。