开心的webpack

学习 https://juejin.im/post/5cecd6fdf265da1b827a7ca5

一直都是直接vue-cli脚手架搭起来的,没怎么自己动手玩过webpack,这次就简单的玩一下~~ 开心

安装

$ npm install webpack webpack-cli -D 或者 npm install webpack webpack-cli --save-dev

起步

npm init -y

生成package.json配置文件

添加基础代码

  • index.html
  <body>
    <p>这是最原始的网页内容</p>
    <div id="root"></div>
    <script src="./dist/main.js"></script>
  </body>
  • index.js
console.log('hello, world')
  • 通过指令touch webpack.config.js新建该文件
  • 编辑webpack.config.js文件
const path = require('path')
module.exports = {
  entry: './index.js',
  output: {
    filename: 'main.js',
    // path配置了打包后的输出目录为dist文件下
    path: path.resolve(__dirname, 'dist')
  }
}

  • 改写package.json文件
  1. 添加private属性并设置为true,此属性能让我们的项目为私有的,防止意外发布代码
  2. 移除main属性,我们的项目并不需要对外暴露一个入口文件
  3. 添加scripts命令,即我们的打包命令
{
  "name": "webpack",
  "version": "1.0.0",
  "description": "",
  "private": true,
  "dependencies": {
    "webpack-cli": "^3.3.7",
    "webpack": "^4.39.3"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "bundle": "webpack" // 打包命令
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

  • 运行以下命令对项目进行打包
npm run bundle

打包成功后,项目目录下就会多出一个dist文件夹,文件夹下有main.js文件
在这里插入图片描述

打包静态资源

什么是loader?

loader是一种打包规则,它告诉了Webpack在遇到非js文件时,应该如何处理这些文件

loader有几种固定的运用规则

  • 使用test正则来匹配相应的文件
  • 使用use来添加文件对应的loader
  • 对于多个loader而言,从右到左以此调用

使用loader打包图片

打包图片需要用到file-loader 或 url-loader

npm install file-loader -D

添加打包图片规则

webpack.config.js文件下添加打包图片规则

module.exports = {
    module: {
        rules:[
            {
                test: /\.(png|jpg|git)$/,
                use: {
                    loader: 'file-loader'
                }
            }
        ]
    }
}
  • 打包后的项目目录

[外链图片转存失败(img-jTqvhUdG-1567437934382)(D:\2019.5月秋招准备\面试题\webpack\2.png)]

2.png这个图片打包到了dist下

运用占位符

从上面的截图可以看得到,打包生成的图片的命名是一堆乱码,如果我们要原样输出原图片的名字的话,又该如何配置呢?

使用占位符进行解决

  • [name] 代表原本文件的名字
  • [ext] 代表原本文件的后缀
  • [hash] 代表一个唯一编码
  module: {
    rules: [
      {
        test: /\.(png|jpg|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name]_[hash].[ext]'
          }
        },
      }
    ]
  }

编译成功后,打包成功的文件命名如下

[外链图片转存失败(img-ikTm3L65-1567437934383)(D:\2019.5月秋招准备\面试题\webpack\1567347564286.png)]

使用loader打包CSS

样式文件分为几种情况,每一种都需要不同的loader来处理

  1. 普通.css文件,使用style-loadercss-loader来处理
  2. .less文件,使用less-loader来处理
  3. .sass或者.scss文件,需要使用sass-loader处理
  4. .styl文件,需要使用style-loader来处理

添加css,并打包

  • 根目录下添加index.css文件

    .avatar {
        width: 50px;
        height: 50px;
    }
    
  • 修改index.js

// 引入index.css文件

...
import './index.css'
var img = new Image()
...

打包文件

[外链图片转存失败(img-mj41g6Ma-1567437934384)(D:\2019.5月秋招准备\面试题\webpack\4.png)]

打包Sass文件

需要安装sass-loader和node-sass (scss/sass都可以用sass-loader打包)

npm install sass-loader node-sass -D

sass的语法格式是一种缩进格式;scss类似于css,大括号格式

  • 添加index-scss.scss文件
body {
  .avatar-scss{
    width: 100px;
    height: 100px;
  }
}
  • 修改index.js
...
import('./index-scss.scss')
img.classList.add('avatar-scss')

打包成功

[外链图片转存失败(img-NOF1HHhP-1567437934384)(D:\2019.5月秋招准备\面试题\webpack\5.png)]

自动添加css厂商前缀

当我们在css文件中写一些需要处理兼容性的样式的时候,需要我们分别对于不同的浏览器添加不同的厂家前缀。可以使用postcss-loader在webpack打包的时候自动添加这些厂家前缀

自动添加厂家前缀需要npm install 安装postcss-loaderautoprefixer

npm install postcss-loader autoprefixer -D
  • webpack.conf.js下添加postcss-loader
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader'] //从右向左顺序调用,所以顺序不可以错
      
      }
  • index.css下添加需要处理兼容性样式
...
transform: translate(50px, 50px)
  • 根目录添加 postcss.config.js
module.exports = {
    plugins: [require('autoprefixer')]
}

进行打包

!!!! 这里蛮奇怪的,打包好了,感觉很成功的,但是控制台没有显示…是我对控制台的理解不够深刻吗?

模块化打包css文件

  • 新建一个createAvatar.js
import avatar from './1.png'
export default function createAvatar () {
  var img = new Image()
  img.src = avatar
  img.classList.add('avatar-scss')

  var root = document.getElementById('root')
  root.appendChild(img)
}

  • 在index.js下引入这个方法
import createAvatar from './createAvatar.js'
createAvatar()

打包效果

[外链图片转存失败(img-YhdwPIEH-1567437934386)(D:\2019.5月秋招准备\面试题\项目记录\3.png)]

发现引进来的方法,会受index下引入的css文件的影响,那么能否消除这个影响呢? 需要开启对css样式文件的模块打包

  • 修改webpack.config.js文件

[外链图片转存失败(img-muZocsmY-1567437934387)(D:\2019.5月秋招准备\面试题\项目记录\4.png)]

  • 修改完成后需对index.js作改动
import style from './index-scss.scss'

img.classList.add(style['avatar-scss'])

打包

[外链图片转存失败(img-fUzI8mvl-1567437934388)(D:\2019.5月秋招准备\面试题\项目记录\5.png)]

avatar下的图片没有受到index下css影响,显示了自己最原本的样子

webpack核心

使用WebpackPlugin

plugin 当webpack运行到某一个阶段,使用plugin来帮我们做一些事情

  • 进行一系列改动 删除不必要文件与移动文件

[外链图片转存失败(img-Bc23BkH4-1567437934389)(D:\2019.5月秋招准备\面试题\项目记录\6.png)]

  • 修改index.js文件
var root = document.getElementById('root')
var dom = document.createElement('div')
dom.innerHTML = 'hello, world'
root.appendChild(dom)

  • 修改webpack.config.js
const path = require('path')
module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    // path配置了打包后的输出目录为dist文件下
    path: path.resolve(__dirname, 'dist')
  }
}

html-webpack-plugin

html-webpack-plugin可以让我们使用固定的模板,在每次打包的时候自动生成一个.html文件,并且它会自动帮我们引入打包后的.js文件

安装

npm install html-webpack-plugin -D
  • 在src目录下新建index.html文件
<!DOCTYPE html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>HTML模板</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <div id="root"</div>
  </body>
</html>

  • 使用html-webpack-plugin 修改webpack.config.js文件
// 引入该plugin
const htmlWebpackPlugin  = require('')

module.exports = {
    ... 其他代码
    plugins: [
        new htmlWebpackPlugin({
    		//使用固定的模板解析index.html
            template: './src/index.html'
        })
    ]
}

打包完成后 dist/index.html 会引入js文件 这是这个plugin帮我们实现的

[外链图片转存失败(img-LGX8IWuH-1567437934389)(D:\2019.5月秋招准备\面试题\项目记录\7.png)]

clean-webpack-plugin

clean-webpack-plugin可以帮我们在打包之前自动删除dist打包目录下的所有文件,不用我们手动删除

SourceMap

良好的source-map配置不仅n能帮助我们提高打包速度,同时在代码维护和调错方面也有很大的帮助,一般来说,sourcemap的最佳实践如下

  • 开发环境下(development):推荐将devtool设置成cheap-module-eval-source-map
  • 生产环境下(production):推荐将devtool设置成cheap-module-source-map

使用WebpackDevServer

webpack-dev-server可以帮助我们在源代码更改的情况下,自动帮我们打包我们的代码并启动一个小型的服务器。如果与热更新一起使用,它能帮助我们高校的开发

自动打包的方案,通常有以下几种

  • watch参数自动打包,虽然能够帮我们自动打包,但我们仍然需要手动刷新浏览器,同时他不能够帮我们在本地启动一个小型服务器,一些http请求不能通过
  • webpack-dev-server插件打包(推荐): 他是我们推荐的一种自动打包方案,在开发环境下使用尤其能够帮我们高效的开发,它能解决watch参数打包中的问题,与热更新

watch参数自动打包

  • 在package.json下
"scripts": {
    ... 其他代码
    "watch": "webpack --watch"
}
  • 运行npm run watch 改变src/index.js中的innerHTML

刷新网页,发现其自动更新了

说明了watch可以实现自动打包的功能,但仍然要刷新

webpack-dev-server打包

要使用webpack-dev-server,需要使用如下命令进行安装

npm install webpack-dev-server -D
  • 在package.json中进行修改
"scripts": {
    "watch": "webpack --watch",
    "dev": "webpack-dev-server"
}
  • 在webpack.config.js中进行修改
module.exports = {
    ... 其他代码
    devServer: {
    	// 以dist文件为基础启动一个服务器,服务器运行在4200端口上,每次启动时自动打开浏览器
    	contentBase: 'dist',
    	open: true,
    	port: 4200
	}
}

!!!!!!!!我好激动,原来vue-cli脚手架npm run dev后自动打开网页 并且修改代码后浏览器也会自动刷新是这样来的!!! 太开心拉~

模块热更新(HMR)

模块热更新的理解:它能够让我们在不刷新浏览器(或自动刷新)的前提下,在运行时帮我们更新最新的代码

模块热更新(HMR)已内置到 Webpack ,我们只需要在webpack.config.js中像下面这样简单的配置即可,无需安装别的东西。

  • 修改webpack.config.js
const webpack = require('webpack')
module.exports = {
    devServer: {
        contentBase: 'dist',
        port: 4200,
        open: true,
        hot: true,
        hotOnly: true
    },
    plugins: [
        new Webpack.HotModuleReplacementPlugin()
    ]
}

css中的模块热更新

  • 在style.css中添加代码
div:nth-of-type(odd) {
  background-color: red;
}
  • 改写src目录下的index.js中的代码
import './style.css'
var btn = document.createElement('buttom')
document.body.appendChild(btn)

btn.onclick = function () {
  var dom = document.createElement('div');
  dom.innerHTML = 'item';
  document.body.appendChild(dom);
}
  • 添加保留处理css文件的loader
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      }
    ]
  }

npm run dev 打包

[外链图片转存失败(img-5k6TohLd-1567437934390)(D:\2019.5月秋招准备\面试题\webpack\7.png)]

理解: 由于item是动态生成的,当我们要将red颜色改变成yellow时,模块热更新能帮我们在不刷新浏览器的情况下改变样式的内容。

js中的模块热更新

  • 在src目录下创建两个.js文件,number.jscounter.js

number.js

export default function number () {
  var dom = document.createElement('div')
  dom.setAttribute('id', 'number')
  dom.innerHTML = '3000'
  document.body.appendChild(dom)
}

counter.js

export default function counter () {
  var dom = document.createElement('div')
  dom.setAttribute('id', 'counter')
  dom.innerHTML = 1
  dom.onclick = function () {
    dom.innerHTML = parseInt(dom.innerHTML, 10) + 1
  }
  document.body.appendChild(dom)
}

  • 添加完以后,对index.js文件做一下改动
import counter from './counter.js'
import number from './number.js'
counter()
number()

打包完成后,使用npm run dev打包,在页面上点击数字1,累加到一定数值。修改number.js下的初始值1000->3000 ,会发现,网页上,1000成功变成了3000,但是累计的数值却重置成1。

  • 对js代码进行额外的模块HMR配置 index.js
if (module.hot) {
    module.hot.accept('./number.js', () => {
        document.body.removeChild(document.getElementById('number'))
        number()
    })
}

这样修改number.js下的number值后,累计的数值就不会发生改变~~

处理ES6语法

我们在项目中书写的ES6代码,由于考虑到低版本浏览器的兼容性问题,需要把ES6代码转换成低版本浏览器可以识别的ES5代码。使用babel-loader@babel/core来进行ES5和ES6之间的链接,使用@babel/preset-env来进行ES6转为ES5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值