webpack基于node,所以想要学习webpack首先要安装node。
webpack4要安装node8.2以上版本。css
为何选择本地安装,主要是因为之后介绍热更新这一部分不会报错,若是全局安装热更新就会报错,以本部分为基础依次介绍,保证各部分不会出错。html
mkdir webpack-test cd webpack-test npm init //初始化npm,都选择默认,文件夹自动建立package.json npm i webpack webpack-cli -D // 本地安装webpack
★ npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies中,主要在开发环境中的依赖包node
webpack4能够支持0配置打包,这里所说的0配置又是什么呢?固然在开发者眼中0配置的东西,那根本是没法用的,由于不够智能,那么咱们就来看看作到了哪些0配置。
在使用webpack进行打包的时候,默认状况下会将src下的入口文件(index.js)进行打包。jquery
a. 根目录下建立文件夹src,并建立index.js文件webpack
document.write('Hello webpack!')
b. 打包测试css3
最后提示:
WARNING in configuration //配置警告
大致意思:是mode没有设置,webpack生产环境没法获取mode值,请设置mode来肯定开发环境仍是生产环境web
// node v8.2版本之后都会有一个npx // npx会执行bin里的文件 npx webpack // 不设置mode的状况下 打包出来的文件自动压缩 npx webpack --mode development // 设置mode为开发模式,打包后的文件不被压缩
当执行npx webpack命令的时候,webpack会自动查找项目中src目录下的index.js文件,而后进行打包,生成一个dist目录并存在一个打包好的main.js文件
这些算是0配置的操做了,名字都是定义好的,不能变,想一想也很鸡肋npm
目录结构:json
webpack.config.js基本配置项:api
module.exports = { entry: '', // 入口文件 output: {}, // 出口文件 module: {}, // 处理对应模块 plugins: [], // 对应的插件 devServer: {}, // 开发服务器配置 mode: 'development' // 模式配置 }
a.根目录下建立src文件夹,并在src目录下建立index.js:
document.write('Hello webpack!')
b.配置文件webpack.config.js:
const path = require('path') module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist') }, mode: 'development' }
c.执行webpack
经过简单打包,在根目录下多出一个文件夹
查看一下dist文件夹下bundle.js可见如下代码,证实打包成功
友情提示:
在咱们每次npm run build的时候都会在dist目录下建立不少打好的包,若是积累过多可能也会混乱,因此应该在每次打包以前将dist目录下的文件都清空,而后再把打好包的文件放进去
这里提供一个clean-webpack-plugin插件
npm i clean-webpack-plugin -D
webpack.config.js中添加如下配置代码:
let CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { plugins: [ // 打包前先清空 new CleanWebpackPlugin('dist') ] }
上边部分咱们测试已经发现,直接打包会警告配置环境,本部分着重介绍一下。
环境配置在package.json文件:
{ "name": "lesson_test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack --mode development", // 开发环境,和上部分npx webpack --mode development对比咱们能够发现点端倪 "build": "webpack --mode production" // 生产环境 }, "author": "", "license": "ISC" }
开发环境和生产环境打包会有什么区别呢?
"dev": "webpack --mode development", // 开发环境,打包后文件是未压缩的文件
"build": "webpack --mode production" // 生产环境,打包后文件是压缩过的文件
配置完成后,经过执行命令:
a. 执行 npm run dev
打包后文件为非压缩文件
b. 执行 npm run build
打包后文件为压缩文件
假如src目录下多个文件入口,又该如何配置webpack.config.js文件呢。
具体方案:
下面就来看看这两种方式的写法,配置代码:
const path = require('path') module.exports = { // 1.写成数组的方式就能够打出多入口文件,不过这里打包后的文件都合成了一个 // entry: ['./src/index.js', './src/login.js'], // 2.真正实现多入口和多出口须要写成对象的方式 entry: { index: './src/index.js', login: './src/login.js' }, output: { // 1. filename: 'bundle.js', // 2. [name]就能够将出口文件名和入口文件名一一对应 //filename: '[name].js', // 打包后会生成index.js和login.js文件 filename: '[name].[hash:16].js', //生成文件名含有16位哈希值 path: path.resolve(__dirname, 'dist') }, mode: 'development' }
执行npm run dev结果
目录结构(生成文件的名字带有16位哈希值):
webpack的核心功能是打包js的,html、style、css、less、sass、img等等须要引入各类loader,到达这一部分,每一步都须要引入对应的插件。
html须要安装html-webpack-plugin插件,开始引入:
npm i html-webpack-plugin -D // 本地安装
由于是个插件,因此须要在webpack.config.js里引用一下。
a. 单文件入口配置
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') // 引入html打包插件 module.exports = { entry: './src/index.js', output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', hash: true // 在html模板中自动添加?20位哈希值 }) ], mode: 'development' }
执行npm run dev 生成目录
打开index.html文件,可见js文件后添加了“?20位哈希值”
b. 多文件入口配置
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,main.js对应的是index.html,这里特地修改成main,方便理解,如下会和目录文件做对比就一目了然了 hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }) ], mode: 'development' }
由目录可见,dist文件夹下生成index.html对应main.js、login.html对应login.js
上面基本介绍完了html和js的打包配置了,如今咱们还缺一个好兄弟css,webpack对css的解析须要用到loader,因此咱们先提早安装好,待会好方便使用
这里涉及到两种样式:
npm i style-loader css-loader -D // style\css // 引入less文件的话,也须要安装对应的loader npm i less less-loader -D
文件目录结构
a. 配置样式
b. 在js文件中引入样式
c. 配置webpack.config.js文件
说明:配置module添加规则,本部分添加可css、less的匹配打包规则
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }) ], mode: 'development' }
d. 执行npm run dev打包
生成静态文件index.html
生成静态文件login.html
本部分也就是将css文件拆分出来,html页面以<link>的方式引入。
// @next表示能够支持webpack4版本的插件 npm i extract-text-webpack-plugin@next -D
配置webpack.config.js
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 引入插件 module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: ExtractTextWebpackPlugin.extract({ // 将css用link的方式引入就再也不须要style-loader了 use: 'css-loader' }) } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], hash: true }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], hash: true }), new ExtractTextWebpackPlugin('css/style.css') // 拆分后会把css文件放到dist目录下的css/style.css ], mode: 'development' }
配置中只对index.html文件引入样式,而login.html没有引入,所以要注释掉login.js引入的样式
// import './less/style.less' // 注释掉这句代码 document.write('<h1 class="color-blue">Welcome to webpack!</h1>')
执行npm run dev,生成dist目录
首页静态页面代码,可见以link的方式引入了css样式
配置webpack.config.js文件
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: 'css-loader' }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], // 必定要注意这里 fallback: 'style-loader' // 缺乏这里也是没法编译less }) } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), styleCss, styleLess ], mode: 'development' }
index.js文件
import './css/style.css' import './less/style.less' // 引入style.less document.write('<h1 class="color-red">Hello webpack!</h1><h2 class="color-blue">测试less样式是否引入</h2>')
执行 npm run dev ,获取静态页面截图,可见所有正常引入
执行效果
生成文件目录:
npm i file-loader url-loader -D
这里着重介绍一下file-loader和url-loader:
url-loader解决的问题:
若是图片较多,会发不少http请求,会下降页面性能。url-loader会将引入的图片编码,生成dataURl。至关于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只须要引入这个文件就能访问图片了。固然,若是图片较大,编码会消耗性能。所以url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。
url-loader和file-loader是什么关系呢?
简答地说,url-loader封装了file-loader。url-loader不依赖于file-loader,即便用url-loader时,只须要安装url-loader便可,不须要安装file-loader,由于url-loader内置了file-loader。
经过上面的介绍,咱们能够看到,url-loader工做分两种状况:
1.文件大小小于limit参数,url-loader将会把文件转为DataURL;
2.文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。所以咱们只须要安装url-loader便可。
若是是在css文件里引入的如背景图之类的图片,就须要指定一下相对路径
webpack.config.js配置:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: 'css-loader', publicPath: '../' // 样式根据相对路径引用到图片资源 }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, // 小于8k的图片自动转成base64格式,而且不会存在实体图片 outputPath: 'images' // 图片输出路径 } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], hash: true }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], hash: true }), styleCss, styleLess ], mode: 'development' }
样式style.css代码:
/* style.css */ @charset "utf-8"; .logo { display: block; width: 222px; height: 222px; background: url(../images/logo.png) no-repeat; // 这里的logo.png大小大于8K,如下生成在dist文件夹下images目录 } .color-red { color: #f00; }
在css中指定了publicPath路径这样就能够根据相对路径引用到图片资源了,以下图所示
执行npm run dev 生成目录结构:
url-loader能自动识别CSS代码中的图片路径并将其打包至指定目录,可是JS就不一样了,咱们来看下面的例子。
// index.js var img = new Image(); img.src = './images/logo.png'; document.body.appendChild(img);
若是不使用Webpack打包,正常状况下只要路径正确图片是可以正常显示的。然而,当使用Webpack打包后,咱们会发现图片并未被成功打包到dist目录,天然图片也没法显示出来。
这实际上是由于Webpack并不知道'../images/logo.png'是一张图片,若是要正常打包的话须要先将图片资源加载进来,而后再将其做为图片路径添加至图片对象。具体代码以下:
// index.js import imgUrl from './images/logo.png' // 引入图片(路径),若是小于8K格式为base64,大于8K为设置路径dist目录下'./images/logo.png' const img = new Image() // 实例一个图片对象 img.src = imgUrl; document.body.appendChild(img); // 添加到dom节点中
完整index.js文件:
import './css/style.css' import './less/style.less' import imgUrl from './images/logo.png' // 引入图片 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // './images/logo.png' document.write('<h1 class="logo"></h1></h1><h1 class="color-red">Hello webpack!</h1><h2 class="color-blue">测试第二个css样式是否引入</h2>')
完整webpack.config.js配置文件(相比第10部分无任何变化):
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: 'css-loader', publicPath: '../' // 样式根据相对路径引用到图片资源 }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', // 图片输出路径 name: '[name].[ext]' } } ] } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), styleCss, styleLess ], mode: 'development' }
执行npm run dev生成文件目录
生成静态文件
可见图片在js中正常加载到页面中,因为logo.png大于8K,被打包到dist文件目录的images文件中。若是图片小于8K,则以base64编码格式写入页面进项渲染。
页面中常常会用到img标签,img引用的图片地址也须要一个loader来进行处理
npm i html-withimg-loader -D
完整wabpack.config.js配置:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: 'css-loader', publicPath: '../' // 样式根据相对路径引用到图片资源 }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', // 图片输出路径 name: '[name].[ext]' } } ] }, { test: /\.(htm|html)$/, use: 'html-withimg-loader' // 引入html-withimg-loader } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), styleCss, styleLess ], mode: 'development' }
打包后生成对应目录:
字体图标和svg图片均可以经过file-loader来解析,在第11部分已经进行安装。
webpack.config.js引入loader
module.exports = { module: { rules: [ { test: /\.(eot|ttf|woff|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'iconfont' // 打包到指定文件夹 } } ] } ] } }
这样即便样式中引入了这类格式的图标或者图片都没有问题了,img若是也引用svg格式的话,配合上面写好的html-withimg-loader就都没有问题了。
在index.js引入样式:
import './css/style.css' import './less/style.less' import './iconfont/iconfont.css' // 引入字体图片 import imgUrl from './images/pic.jpg' // 引入图片连接 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // './images/logo.png' document.write('<h1 class="logo"></h1></h1><h1 class="color-red">Hello webpack!</h1><h2 class="color-blue">测试第二个css样式是否引入</h2><br><span class="iconfont icon-gouwuche"></span>')
完整的webpack.config.js配置:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: 'css-loader', publicPath: '../' // 样式根据相对路径引用到图片资源 }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', // 图片输出路径 name: '[name].[ext]' } } ] }, { test: /\.(eot|ttf|woff|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'iconfont' // 打包到指定文件夹 } } ] }, { test: /\.(htm|html)$/, use: 'html-withimg-loader' // 引入html-withimg-loader,将图片转化为base64图片 } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], hash: true }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], hash: true }), styleCss, styleLess ], mode: 'development' }
打包后目录文件:
对应静态文件
经过postcss中的autoprefixer能够实现将CSS3中的一些须要兼容写法的属性添加响应的前缀,这样省去咱们很多的时间
npm i postcss-loader autoprefixer -D // 安装postcss-loader 和 autoprefixer
安装后,咱们还须要像webpack同样写一个config的配置文件,在项目根目录下建立一个postcss.config.js文件,配置以下:
const Autoprefixer = require('autoprefixer') module.exports = { plugins : [ Autoprefixer ] }
而后在webpack里配置postcss-loader,webapack.config.js完整代码:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: ['css-loader', 'postcss-loader'], // 配置postcss-loader fallback: 'style-loader', publicPath: '../' }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', name: '[name].[ext]' } } ] }, { test: /\.(eot|ttf|woff|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'iconfont' } } ] }, { test: /\.(htm|html)$/, use: 'html-withimg-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], hash: true }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], hash: true }), styleCss, styleLess ], mode: 'development' }
index.js添加测试元素
样式表style.css,简单书写了animation动画效果,没有添加兼容浏览器的前缀
/* style.css */ @charset "utf-8"; .logo { display: block; width: 222px; height: 222px; background: url(../images/logo.png) no-repeat; } .color-red { color: #f00; } .test-css3 { position: absolute; left: 500px; top: 0; width: 100px; height: 100px; background-color: #f00; animation: myfirst 5s linear 2s infinite alternate running; } @keyframes myfirst { 0% { background: #f00; left: 500px; top: 0; } 25% { background: #ff0; left: 900px; top: 0; } 50% { background: #f0f; left: 900px; top: 400px; } 75% { background: #000; left: 500px; top: 400px; } 100% { background: #0f0; left: 500px; top: 0; } }
执行npm run dev 后生成的style.css代码自动添加了-webkit-前缀
在实际开发中,咱们在大量的使用着ES6及以后的api去写代码,这样会提升咱们写代码的速度,不过因为低版本浏览器的存在,不得不须要转换成兼容的代码,因而就有了经常使用的Babel。
bable能够将ES6代码转义ES5代码,安装以下:
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 -D
babel兼容ES6和草案api,经过一个.babelrc文件来配置一下,对这些版本的支持
// .babelrc { "presets": ["env", "stage-0"] // 从右向左解析 }
咱们再在webpack里配置一下babel-loader既能够作到代码转成ES5了
module.exports = { module: { rules: [ { test:/\.js$/, use: 'babel-loader', include: /src/, // 只转化src目录下的js exclude: /node_modules/ // 排除掉node_modules,优化打包速度 } ] } }
添加本部分配置,完整wabpack.config.js代码:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') const CleanWebpackPlugin = require('clean-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: ['css-loader', 'postcss-loader'], fallback: 'style-loader', publicPath: '../' // 样式根据相对路径引用到图片资源 }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.js$/, use: 'babel-loader', include: '/src/', exclude: '/node_modules/' }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', // 图片输出路径 name: '[name].[ext]' } } ] }, { test: /\.(eot|ttf|woff|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'iconfont' // 打包到指定文件夹 } } ] }, { test: /\.(htm|html)$/, use: 'html-withimg-loader' // 引入html-withimg-loader,将图片转化为base64图片 } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', chunks: ['main'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', chunks: ['login'], // 对应关系,index.js对应的是index.html hash: true // 在html模板中自动添加?20位哈希值 }), styleCss, styleLess, new CleanWebpackPlugin('dist') ], mode: 'development' }
A.启动静态服务
启动一个静态服务器,默认会自动刷新,就是说你对html,css,js文件作了修改并保存后,浏览器会默认刷新一次展示修改后的效果
module.exports = { devServer: { contentBase: './dist', host: 'localhost', // 默认是localhost port: 8080, // 端口 open: true, // 自动打开浏览器 // hot: true // 开启热更新 } }
此时咱们要对pakage.json文件进行修改:
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production", "dev": "webpack-dev-server --mode development --open" // 使用webpack-dev-server }
执行npm run dev 会自动打开默认浏览器,打开http://localhost:8080页面,html,css,js修改保存后页面会自动实时更新。
以前各部分咱们每次执行npm run dev都会在根目录生成静态文件目录dist,启动静态服务器,生成dist会储存到内存当中,根目录下再也不生成dist文件夹。
B.热更新
在配置devServer的时候,若是hot为true,就表明开启了热更新
module.exports = { devServer: { contentBase: './dist', host: 'localhost', // 默认是localhost port: 8080, // 端口 open: true, // 自动打开浏览器 hot: true // 开启热更新 } }
可是热更新是指定某个js文件的更新,只需在指定的js文件添加如下代码,表示本文件实现热更新,修改文件后手动刷新页面,会看到修改后的内容;若是不添加如下代码,js文件仍是自动刷新
if (module.hot) { // 实现热更新 module.hot.accept(); }
热更新和自动刷新的区别:
完整webpack.config.js代码:
const path = require('path') const webpack = require('webpack') // 引入webpack const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin') const CleanWebpackPlugin = require('clean-webpack-plugin') // 样式处理 const styleCss = new ExtractTextWebpackPlugin('./css/style.css') const styleLess = new ExtractTextWebpackPlugin('./css/style2.css') module.exports = { entry: { main: './src/index.js', login: './src/login.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: styleCss.extract({ use: ['css-loader', 'postcss-loader'], fallback: 'style-loader', publicPath: '../' }) }, { test: /\.less$/, use: styleLess.extract({ use: ['css-loader', 'less-loader'], fallback: 'style-loader' }) }, { test: /\.js$/, use: 'babel-loader', include: '/src/', exclude: '/node_modules/' }, { test: /\.(jpe?g|png|gif)$/, use: [ { loader: 'url-loader', options: { limit: 8192, outputPath: 'images', name: '[name].[ext]' } } ] }, { test: /\.(eot|ttf|woff|svg)$/, use: [ { loader: 'file-loader', options: { outputPath: 'iconfont' } } ] }, { test: /\.(htm|html)$/, use: 'html-withimg-loader' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', filename: 'index.html', title: '首页测试', chunks: ['main'], hash: true }), new HtmlWebpackPlugin({ template: './src/login.html', filename: 'login.html', title: '登陆页测试', chunks: ['login'], hash: true }), styleCss, styleLess, new CleanWebpackPlugin('dist'), new webpack.HotModuleReplacementPlugin() ], devServer: { contentBase: path.join(__dirname, 'dist'), host: 'localhost', port: 8080, open: true, hot: true // 实现页面热更新 }, resolve: { extensions: ['.js', '.json', '.css'] }, mode: 'development' }
index.js文件代码:
import './css/style.css' import './less/style.less' import './iconfont/iconfont.css' import imgUrl from './images/pic.jpg' // 引入图片 const img = new Image() img.src = imgUrl document.body.appendChild(img) // document.write(imgUrl) // './images/logo.png' document.write('<h1 class="logo"></h1></h1><h1 class="color-red">Hello webpack!</h1><h2 class="color-blue">测试第二个css样式是否引入</h2><br><span class="iconfont icon-gouwuche"></span><span class="iconfont icon-new"></span><div class="test-css3"></div>') if (module.hot) { module.hot.accept() }
在webpack的配置中,resolve咱们经常使用来配置别名和省略后缀名
module.exports = { resolve: { // 别名 alias: { $: './src/jquery.js' }, // 省略后缀 extensions: ['.js', '.json', '.css'] }, }
未完待续
参考连接:
一、https://juejin.im/post/5adea0...
二、https://www.cnblogs.com/cisum...
三、https://www.cnblogs.com/golov...
四、https://www.webpackjs.com/loa...
五、https://www.cnblogs.com/golov...