【One by one系列】一步步学习webpack打包
Webpack Quick Start
1.webpack到底是什么?
前端资源加载/打包工具
js→js→png→less→sass
- 静态分析模块的依赖关系
- 组织合并打包生成对应的静态资源
2.webpack4新特性
2.1 mode属性
development
- 浏览器调试工具
- 注释、开发阶段的详细错误日志和提示
- 快速和优化的增量构建机制
production
- 开启所有的优化代码
- 更小的bundle大小
- 去除掉只在开发阶段运行的代码
- Scope hoisting(作用域)和Tree-shaking(引入但是没有使用,抖掉)
?
webpack --mode development
2.2 开箱即用webassembly
2.3 支持多种模块类型
- javascript/auto
- javascript/esm
- javascript/dynamic
- json
- webassembly/experimental
2.4 0CJS
0配置,webpack4
受Parcel
打包工具启发,尽可能的让开发者运行项目的成本变低。webpack4
不再强制需要webpack.config.js
作为打包的入口配置文件,默认的入口为./src/
和默认的出口./dist
,小项目的福音。
2.5 新的插件系统
提供了针对插件和钩子的新API。
- 所有的hook由hooks对象统一管理,它将所有的hook作为可扩展的类属性。
- 当添加插件时,必须提供一个插件名称
- 开发插件时,可以选择
sync
/callback
/promise
作为插件类型 - 可以通过
this.hooks={myHook:new SyncHook(...)}
来注册hook了
2.6 node.js>=8.9.4
3.安装
3.1本地安装
cnpm install --save-dev webpack
npm install --save-dev webpack-cli
3.2全局安装
npm install --global webpack
- 不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。
4.Quick Start
4.1新建文件夹
mkdir webpack-demo
4.2新建文件
index.js
/** * es6 * 写法 * * */ import { hello } from './hello_module' hello.sayHello() /** * node.js * 写法 */ // let hello=require('./hello_module') // hello.sayHello();
hello_module.js
/** * es6 */ export default{ sayHello:function () { console.log("hello") } } /** * nodejs */ module.exports = { sayHello: function () { console.log("hello") } }
4.3打包
.\node_modules\.bin\webpack --mode development index.js -o output_test_d.js
5kb
.\node_modules\.bin\webpack --mode production index.js -o output_test_p.js
2kb
5.配置文件
webpack.config.js
const path=require('path') module.exports={ entry:'./input.js', //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'output.bundle.js' } }
const path=require('path') module.exports={ entry:{ home:'./home.js' about:'./about.js' other:'./other.js' }, //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' //name->home or about or other }, mode:"development" }
$:webpack
6.Loaders
webpack预处理源文件,例如ts->js
- Files
- JSON
- Transpiling
- Templating
- Styling
- Linting&&Testing
- Frameworks
6.1 url-loader
当文件的大小小于某个指定size时,转成DataURL
,base64,不做雪碧图。
npm install url-loader --save-dev
import img from ‘./image.png‘
//webpack.config.js module.exports={ module:{ rules:[ test:/\.(png|jpg|gif)$/i, use:[{ loader:'url-loader', options:{ limit:8192 } }] ] } }//当文件是png,jpg,gif时,会使用url-loader来进行处理,文件小于8k时,会把文件以DataUrl的形式存储在文件中
6.2 babel-loader
负责把es6,es7的代码转化为es5的代码
- 安装
npm install -D babel-loader @babel/core @babel/preset-env webpack
moudule:{ rules:[ { test:/\.m?js$, exclude:/(node_modules|bower_components), use:{ loader:'babel-loader', options:{ presets:['@babel/preset-env'] } } } ] }
6.3 sass-loader
npm install sass-loader node-sass -D
npm install style-loader css-loader --save-dev
//webpack.config.js module.exports={ .. module:{ rules:[{ test:/\.scss$/, use:[ "style-loader", "css-loader", "sass-loader" ] }] } }
7. Plugins插件
7.1 MinCssExtractPlugin.loader
css合并到一起
- 安装
npm install mini-css-extract-plugin -D
const MiniCssExtractPlugin=require("min-css-extract-plugin"); module.exports={ entry:{ home:'./home.js' about:'./about.js' other:'./other.js' }, //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' //name->home or about or other }, mode:"development", plugins:[ new MiniCssExtractPlugin({ filename:"[name].css",//name->home chunkFilename:"[id].css" }) ], module:{ rules:[{ test:/\.scss$/, use:[ MinCssExtractPlugin.loader, "css-loader", "sass-loader" ] }] } }
7.2 DefinePlugin
const path=require('path'); const MiniCssExtractPlugin=require("min-css-extract-plugin"); const webpack=require('webpack') module.exports={ entry:{ home:'./home.js' about:'./about.js' other:'./other.js' }, //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' //name->home or about or other }, mode:"development", plugins:[ new MiniCssExtractPlugin({ filename:"[name].css",//name->home chunkFilename:"[id].css" }), new webpack.DefinePlugin({ 'SERVICE_URL':JSON.stringify('http://www.sina.com') })//就可以直接在js文件中使用SERVICE_URL中使用 ], module:{ rules:[{ test:/\.scss$/, use:[ MinCssExtractPlugin.loader, "css-loader", "sass-loader" ] }] } }
7.3 HtmlWebpackPlugin
- 安装
npm install --save-dev html-webpack-plugin
npm install html-webpack-plugin -D
const path=require('path'); const MiniCssExtractPlugin=require("min-css-extract-plugin"); const webpack=require('webpack'); const HtmlWebpackPlugin=require('html-webpack-plugin'); module.exports={ entry:{ home:'./home.js' about:'./about.js' other:'./other.js' }, //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' //name->home or about or other }, mode:"development", plugins:[ new MiniCssExtractPlugin({ filename:"[name].css",//name->home chunkFilename:"[id].css" }), new webpack.DefinePlugin({ 'SERVICE_URL':JSON.stringify('http://www.sina.com') }),//就可以直接在js文件中使用SERVICE_URL中使用 new HtmlWebpackPlugin() ], module:{ rules:[{ test:/\.scss$/, use:[ MinCssExtractPlugin.loader, "css-loader", "sass-loader" ] }] } }
8.热替换-自动刷新
安装
npm install webpack-dev-server -D
const path=require('path'); const MiniCssExtractPlugin=require("min-css-extract-plugin"); const webpack=require('webpack'); const HtmlWebpackPlugin=require('html-webpack-plugin'); module.exports={ entry:{ home:'./home.js' about:'./about.js' other:'./other.js' }, //入口文件 output:{ path:path.resolve(__dirname,'dist'), filename:'[name].bundle.js' //name->home or about or other }, devServer:{ contentBase:path.join(__dirname,'dist'), compress:true, port:8080 }, mode:"development", plugins:[ new MiniCssExtractPlugin({ filename:"[name].css",//name->home chunkFilename:"[id].css" }), new webpack.DefinePlugin({ 'SERVICE_URL':JSON.stringify('http://www.sina.com') }),//就可以直接在js文件中使用SERVICE_URL中使用 new HtmlWebpackPlugin() ], module:{ rules:[{ test:/\.scss$/, use:[ MinCssExtractPlugin.loader, "css-loader", "sass-loader" ] }] } }
{ "scripts": { "start": "webpack-dev-server"//会去node_modules寻找 }, "devDependencies": { "webpack": "^4.41.6", "webpack-cli": "^3.3.11" } }
热启动:npm run start