Webpack(笔记一)

Webpack(笔记一)

简介:初识Webpack、Webpack核心概念、进阶、实战配置案例、webpack底层原理及脚手架工具分析

1.1 Webpack概念

  • 定义:模块打包工具
  • 几种引入规范:
1、ES Module 模块引入方式:
import export(构造函数)

2、CommonJS 模块引入规范:
require(跟Node一样)
module.exports
3、CMD
4、ADM

1.2 安装与使用

  1. 安装:
npm init 项目名
npm install webpack webpack-cli -D
  1. 使用(生成main.js):
npx webpack index.js
  • 注:npx会帮我们在项目目录中的node_modules查找webpack

1.3 webpack配置

  • 默认配置文件:webpack.config.js(需手动创建)。
const path = require('path');

module.exports = {
	//配置模式,默认是production(会压缩js),可以是development(就不会压缩)
	mode: 'production',
	//entry表示文件打包的起点
	entry: './index.js',
	//output表输出
	output: {
		//表示打包后放置的js文件
		filename: 'bundle.js',
		//表示输出路径,要加绝对路径,所以引用path模块
		path: path.resolve(__dirname, 'bundle')
	}
}
  • entry的值如果是一个文件路径,默认其Chunk Names为main,其值可以是一个对象的形式。
entry: {
    main: './index.js'
}
  • 也可以修改配置文件的名字
npx webpack --config webpackconfig.js
webpackconfig是想要的配置名
  • 配置完成后,以后直接npx webpack即可对模块进行打包。也可以修改package.json的文件,修改指令。
package.json:
"script": {
    "自定义": "webpack"
}
npm run 自定义
即可实现对模块进行打包(注意此处用npm即可)

1.4 配置打包其他文件(除js)

  • 上边的webpack配置仅限于打包js文件,要配置打包其他类型的文件,用module配置。要安装file-loader或其他模块(vue-loader,url-loader)。
const path = require('path')
module.exports = {
	mode: 'production',
	entry: './index.js',
	module: {
	  rules: [{
	    //正则式测试文件后缀
	    test: /\.jpg$/,
	    //使用对应API处理
	    use: {
	        loader: 'file-loader',
	        //保证打包后图片名字不变
	        options:{
	   //还有其他占位符,例如[hash]
	            name: '[name].[ext]',
				//修改文件生成位置
			    outputPath: 'images/'
	        }
	    }
	  }]  
	},
	output: {
		filename: 'bundle.js',
		path: path.resolve(__dirname, 'bundle')
	}
}
  • url-loader也可以用来处理图片,处理后返回的是一段base64格式写在js中的代码。(适用于比较小的图片的打包),使用limit限制打包图片的大小。
module: {
    rules: [{
        test: /\.jpg|.png|.gif$/,
        use: {
            loader: 'url-loader'
            option: {
                name: '[name].[ext]',
                outputPath: 'images/',
                //超过2kb的图片不会被打包
                limit: 2048
            }    
        }
    }]
}

1.5 样式打包

  • style-loader、css-loader、sass-loader和postcss-loder(css3自动添加厂商前缀,例如-webkit)。
  • 至少要有style和css-loader,css-loader帮我们分析处理代码import各CSS模块间的关系,而style-loader则会将代码挂载到head中。
基本安装:
npm install style-loader css-loader -D

处理sass:
npm install sass-loader node-sass -D

处理css3(自动添加内核前缀):
npm install postcss-loader autoprefixer -D
需要配置postcss.config.js:
module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}
  • 多个loader使用时,是自下至上的,且use的值是一个数组。数据的item可以是各种loader或一个用于配置loader的对象。
webpack.dev.js:
(development开发模式下)
module: {
  rules: [{
    test: /\.scss$/,
    //使用多个loader,use是个数组
      use: [
      //从下到上依次处理
        'style-loader',
        //要配置loader时,改为对象
        {
          loader: 'css-loader',
    //保证二级引入的css也得到处理
          options: {
            importLoaders: 2,
            //让css有模块的概念
            modules: true
          }
        },
        'sass-loader',
        'postcss-loader'
      ]
  }, {
      test: /\.css$/,
      use: ['style-loader','css-loader','pstcss-loader']
  }]
}

webpack.prod.js:
(上线打包时)
module: {
  rules: [{
    test: /\.scss$/,
    use: [
      //注意:此处替代了style-loader
      //使得上线时CSS单独打包成独立文件
        MiniCssExtractPlugin.loader,
        {
          loader: 'css-loader',
          options: {
            importLoaders: 2,
            modules: true
          }
        },
        'sass-loader',
        'postcss-loader'
      ]
    }, {
    test: /\.css$/,
    use: [
      MiniCssExtractPlugin.loader,
      'css-loader',
      'pstcss-loader'
      ]
    }]
},
optimization: {
//对css文件进行压缩
    minimizer: [new OptimizeCSSAssetsPlugin({})]
},
plugins: [
//引入和配置css处理插件
    new MiniCssExtractPlugin({
        filename: '[name].css',
        chunkFilename: '[name].chunk.css'
    })
],
output: {
    filename: '[name].[contenthash].js',
    chunkFilename: '[name].[contenthash].js'
}
  • 字体文件(iconfont)用file-loader处理即可。

2 使用plugins(插件)便捷打包

2.1 html-webpack-plugin

  • 首先安装html-webpack-plugin,配置如下(载入并实例化),会使得npx webpack打包其他模块的同时,生成一个html页面(且自动引入js文件)
webpack.config.js:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    //实例化的同时,配置html
    plugins: [new HtmlWebpackPlugin({
        template: 'src/index.html'
    })]
}
  • 作用:可以在webpack运行到某个时刻的时候,帮你完成一些事(类似Vue中生命周期钩子)

2.2 clear-webpack-plugin(重建时,清空dist)

  • 安装:clean-webpack-plugin -D
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
	plugins: [new HtmlWebpackPlugin({
		template: 'src/index.html'
	}), new CleanWebpackPlugin(['dist'])]
}

3 配置

https://www.webpackjs.com/configuration/

3.1 Entry与Output的基础配置

  • 打包多个js,entry和output配置。
  • entry的值改为对象,键为文件名,值为相对路径下要打包的js。
  • output配置:filename的值利用占位符[name],publicPath为传输地址。
module.exports = {
    entry: {
        main: './src/index.js',
        other: './src/abc.js'
    },
    output: {
    //配置传输地址(默认同级目录)
        publicPath: 'http://cdn.com.cn'
    //用占位符生成entry对应键名的js文件
        filename: '[name].js'
        path: path.resolve(__dirname,'dist')
    }
}

3.2 SourceMap

https://www.webpackjs.com/configuration/devtool/

  • 作用:用于与生成的js形成映射关系,也就是能让页面告知是哪个具体的js文件哪行出错,而非直接告诉打包后的js文件哪行出错。
  • 配置:
devtool: 
'source-map':会生成一个map文件
或'inline-source-map':将map内容写入main.js中
或'cheap-source-map':跟第二个类似,不过它错误定位精确度比较低点,但速度是前三者最快的。
或'eval':最快的,但错误提示内容比较少。


上线(production)使用:'cheap-module-source-map':模块出错也会管理。
开发(development)过程:'cheap-module-eval-source-map'

3.3 WebpackDevServer

https://www.webpackjs.com/configuration/dev-server/

  • 类似nodemon,当相关文件改变时,自动重新打包。利用webpack --watch
package.json:
"scripts": {
    "watch": "webpack --watch"
}
运行:
npm run watch即可
  • 使用devServer后打包的文件不会生成dist目录,而是放到内存中
  • devServer配置服务器(放置文件、是否自动打开和端口号)
module.exports = {
	// 服务器
	devServer: {
		//当访问api时会自动转到端口号3000的服务器上
		proxy: {
			'/api': 'http://localhost:3000'
		},
		//指定好服务器js文件放置位置
		contentBase: path.join(__dirname, 'dist'),
		//自动帮你打开浏览器和主页
		open: true,
		port: 8080
	}
}
package.json:
"scripts": {
    "start": "webpack-dev-server"
}
运行:
npm run start
或npx webpack-dev-server
  • proxy配置项详细:
    devServer: {
    //代理请求转发
        proxy: {
            '/api': {
                target: 'http:...',
                //true时只对https生效
                secure: false,
                //能转换拿到demo.json
                pathRewrite: {
                    'header.json': 'demo.json'
                } 
            }
        },
        //拦截
        bypass: function(),
        //使得可以跨域访问
        changeOrgin: true,
        headers: {
            host: 'www.xx.com',
            cookie:  'xxxx'
        }
    }

3.4 Node.Js API

https://www.webpackjs.com/api/node/

  • node.js实现启动服务器时自动webpack打包
server.js:
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const config = require('./webpack.config.js');
//生成编译器,能自动执行打包
const complier = webpack(config);

const app = express();

//利用中间件webpackDevMiddleware
app.use(webpackDevMiddleware(complier, {
  publicPath: config.output.publicPath
}))
app.listen(3000, () => {
  console.log('Server is running')
})
运行:
node server.js

3.5 Hot Module Replacement(模块热替换)

https://www.webpackjs.com/api/hot-module-replacement/

  • HMR:改变样式时,页面不会重新加载(导致动态添加节点小时),但样式能动态改变。方便调试样式。
//需要用到webpack
const webpack = require('webpack');

module.exports = {
	devServer: {
		proxy: {
			'/api': 'http://localhost:3000'
		},
		contentBase: path.join(__dirname, 'dist'),
		open: true,
		port: 8080,
		//让页面保持缓存状态
		hot: true,
		hotOnly: true
	},
	plugins: [
	    new HtmlWebpackPlugin({
	        template: 'src/index.html'
	    }),
	    new CleanWebpackPlugin(),
	    //配置使用该插件
	    new webpack.HotModuleReplacementPlugin()
	]
}
  • 有两个以上实例要发生变动时,利用module.hot使实例间互不影响。
Counter();
Number();

if(module.hot) {
//利用accept方法
  module.hot.accept('./number.js', () => {
    let temp = document.getElementById('number')
    temp.remove()
    Number();
  })
}

3.6 Babel处理ES6语法

https://babeljs.io/setup#installation

  • 目的:将ES6的语法转化为ES5,利用babel-loader处理js文件,配置.babelrc文件处理ES6的新增方法。
.babelrc(写业务代码时用parsets配置):
{  
  "presets": [
    [
			"@babel/preset-env",
        {
			"targets": {
				"chrome": "58",
				"ie": "6"
        },
			"useBuiltIns": "usage",
			"corejs": { "version": 3, "proposals": true}
      }
    ]
  ]
}
.babelrc(写内库时,避免全局污染,用plugins):
{
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 3,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
      }
    ]
  ]
}
  • babel-loader安装与配置:
安装:
npm install --save-dev babel-loader @babel/core
起建立通信作用
npm install @babel/preset-env --save-dev
起转化作用

配置:
module: {
  rules: [{ 
    test: /\.js$/,
    exclude: /node_modules/,
    loader: "babel-loader"
    //配置preset
    options: {
        preset: ["@babel/preset-env"]
    }
  }]
}
  • bebal-loader和babal/present-env只能转化部分语法,ES6的新方法则不行。还需要使用@babel/polyfill
  • @babel/polyfill在7.4.0中已弃用
https://babeljs.io/docs/en/babel-polyfill

安装:
npm install --save @babel/polyfill

配置:
{
	test: /\.js$/,
	exclude: /node_modules/,
	loader: 'babel-loader',
	    options: {
			presets: [
			[
			    '@babel/preset-env', 
			    {
			    //只打包用到的部分
			    	useBuiltIns: 'usage'
		        }
		    ]
		]
	}
}

使用(新版本已弃用):
import "@babel/polyfill";
或require("@babel/polyfill");

  • 配置presets使用core-js(写业务代码时,平时项目使用
安装:
npm install core-js@3 --save

{
	test: /\.js$/,
	exclude: /node_modules/,
	loader: 'babel-loader',
	options: {
		presets: [
			[
			'@babel/preset-env',
			{						   
			// 控制最低浏览器版本号
			    {
					'targets': {
						'chrome': '58',
						'ie': '6'
				},
			// 配置对有需要的代码进行转换
				useBuiltIns:'usage',
				corejs: { version: 3, proposals: true }
				}
			]
		]
	}
}
  • @babel/plugin-transform-runtime(写内库时,防止全局污染)
https://babeljs.io/docs/en/babel-plugin-transform-runtime

安装:
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
npm install --save @babel/runtime-corejs3

配置:
options: {
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "absoluteRuntime": false,
        "corejs": 3,
        "helpers": true,
        "regenerator": true,
        "useESModules": false
      }
    ]
  ]
}
  • 可以把配置写成一个文件名为“.babelrc”的文件。这样就可以把option去除掉。
module: {
rules: [
        {
			test: /\.js$/,
			exclude: /node_modules/,
			loader: 'babel-loader'
        }
    ]
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值