本文会一步一步从 webpack 安装, NPM 脚本命令添加, 各个插件的作用和安装及配置一步一步说明, 如果不想看, 可以跳到文末, 我会把所有安装的插件和配置汇总放在最后.
1. 安装 webpack 和 webpack-cli
NPM install --save-dev webpack webpack-cli
新建 src 目录, 此为源文件目录
因为非全局安装, webpack 没加入全局变量, 只能通过 npx 执行命令
npx webpack // npx 为 NPM 5.2 后增加的命令
打包后会生成 dist 目录, 此为打包文件的目录
├── / 项目目录(根目录)
│ ├── /src(源文件目录)
│ └── index.JS
│ ├── /dist(打包文件生成目录)
│ └── main.JS
│ ├── /node_modules(包安装目录)
│ └── ......
│ ├── package-lock.JSON
│ └── package.JSON
2. 为 NPM 添加命令
使用过 vue.js 的脚手架 vue-cli 的话, 会常用到命令如:
NPM run dev
其实这个是 vue-cli 在 NPM 中配置好的.
在 package.JSON 的 scripts 中就可以配置脚本:
- // ...
- "scripts": {
- "build": "webpack --config webpack.config.js",
- },
- // ...
上述配置会增加一个打包命令:
NPM run build
3. 配置 webpack
在根目录新建 webpack.config.JS 如下:
- const path = require('path')
- module.exports = {
- entry: './src/index.js', // 入口文件
- output: {
- filename: 'bundle.[hash].js', // 默认为 main.JS
- path: path.resolve(__dirname,'./dist') //path 为绝对路径, 用 node path 模块转化
- },
- mode: 'development' // 开发模式
- }
entry 为入口源文件
output 为打包后生成文件的设置, 其中 filename 为生成的文件名,[hash]为随机哈希字符串, 避免缓存. path 为打包文件生成的目录.
mode 为打包的模式, 默认为 production(生产模式), 会压缩代码. development(开发模式)不会压缩代码, 便于阅读.
tips: 打包文件使用 [hash] 后, 每次打包都会生成新的文件, 久了会产生大量冗余文件, 这个时候就需要用到 clean-webpack-plugin 来清除老版本文件.
NPM i clean-webpack-plugin -D // i 等于 install, -D 等于 --save-dev
webpack.config.JS 里引入
- // ...
- const CleanWebpackPlugin = require('clean-webpack-plugin')
- module.exports = {
- // ...
- plugins:[ // 存放插件
- new CleanWebpackPlugin()
- ]
- }
此时的 webpack.config.JS 长这个样子:
- const path = require('path')
- const CleanWebpackPlugin = require('clean-webpack-plugin')
- module.exports = {
- entry: './src/index.js', // 入口文件
- output: {
- filename: 'bundle.[hash].js', // 默认为 main.JS [hash]是为了避免 JS 缓存
- path: path.resolve(__dirname,'./dist') //path 为绝对路径, 用 node path 模块转化
- },
- mode: 'development', // 开发模式
- plugins:[ // 存放插件
- new CleanWebpackPlugin()
- ]
- }
现在, 每次打包前, 都会清空 dist 目录
4. 自动生成 html
目前打包只能生成 JS 文件, 每次都还要手动的去 HTML 文件中引用, 十分不方便, 如果需要自动生成 HTML, 则要用到 HTML-webpack-plugin:
NPM i HTML-webpack-plugin -D
在 src 目录下新建模版 HTML
- <!DOCTYPE HTML>
- <HTML lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>
- 模板
- </title>
- </head>
- <body>
- HTML
- </body>
- </HTML>
webpack.config.JS 里引入
- const HtmlWebpackPlugin = require('html-webpack-plugin')
- module.exports = {
- // ...
- plugins:[
- // ...
- new HtmlWebpackPlugin({
- template: './src/index.html', // 模板位置
- filename: 'index.html', // 生成的 HTML 文件名, 默认也是 index.HTML
- minify: {
- removeAttributeQuotes: true, // 删除标签属性的双引号
- collapseInlineTagWhitespace: true, // 删除多余空格
- },
- hash: true // 增加 hash, 避免缓存
- })
- ]
- }
现在, 每次打包, 会在 dist 目录中生成一个 index.HTML, 并自动引入 JS 文件
5. 配置本地开发服务器
本地开发服务器可以不用每次都打包生成文件, 再去看效果:
NPM i webpack-dev-server -D
webpack.config.JS 里引入
- devServer:{ // 开发服务器配置
- port: 3000, // 端口号
- progress: true, // 进度条
- contentBase: './static', // 服务默认指向文件夹, 静态资源
- inline: true, // 设置为 true, 当源文件改变的时候会自动刷新
- historyApiFallback: true, // 在开发单页应用时非常有用, 它依赖于 HTML5 history API, 如果设置为 true, 所有的跳转将指向 index.HTML
- hot: true, // 允许热加载
- open: true // 自动打开浏览器
- }
启动这个服务可以通过如下命令启动
npx webpack-dev-server
也可以在 package.JSON 的 scripts 脚本配置:
- "scripts": {
- "build": "webpack --config webpack.config.js",
- "dev": "webpack-dev-server"
- }
运行
NPM run dev
则自动在浏览器打开了一个服务.
到此, 目录结构 如下:
├── / 项目目录(根目录)
│ ├── /src(源文件目录)
│ ├── index.HTML
│ └── index.JS
│ ├── /dist(打包文件生成目录)
│ ├── index.HTML
│ └── bundle.2957e949a4a4bf4735f3.JS
│ ├── /node_modules(包安装目录)
│ └── ......
│ ├── /static(静态资源目录)
│ └── ......
│ ├── package-lock.JSON
│ ├── package.JSON
│ └── webpack.config.JS
6. CSS 模块的配置
引入 CSS 文件, 一般是在 HTML 中通过 link 标签引入, 或者在 JS 中
require('./style.css')
因为 webpack 默认不识别 CSS,Less, 则需要安装各种 ** loader** :
NPM i CSS-loader style-loader Less Less-loader -D
在 webpack.config.JS 中加入 loader :
- // ...
- module.exports = {
- // ...
- module: {
- rules: [
- {
- test: /\.CSS$/, // JS 中 require CSS
- use: ['style-loader','css-loader']
- },
- {
- test: /\.Less$/,
- // 注意顺序!
- use: ['style-loader','css-loader','less-loader']
- }
- ]
- },
- plugins:[
- // 存放插件
- ],
- devServer:{
- // 开发服务器
- }
- }
7. ES6 处理
目前的浏览器对 ES6 语法支持都不完整, 需要转化成 ES5 才能执行:
NPM install babel-loader @babel/core @babel/preset-env -D
在 webpack.config.JS 中加入 :
- // ...
- module.exports = {
- // ...
- module: {
- rules: [
- // ...
- {
- test: /\.m?JS$/,
- exclude: /(node_modules|bower_components)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env']
- }
- }
- }
- ]
- },
- plugins:[
- // 存放插件
- ],
- devServer:{
- // 开发服务器
- }
- }
es6 内置方法转化:
- NPM i @babel/plugin-transform-runtime -D
- NPM install --save @babel/runtime @babel/polyfill // 这个正式环境也要用
babel-runtime 和 babel-polyfill 的作用介绍和使用
上面的 webpack.config.JS 改为 :
- // ...
- module.exports = {
- // ...
- module: {
- rules: [
- // ...
- {
- test: /\.m?JS$/,
- exclude: /(node_modules|bower_components)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env'],
- plugins:[ // es6 内置函数转换
- '@babel/plugin-transform-runtime'
- ]
- }
- }
- }
- ]
- },
- plugins:[
- // 存放插件
- ],
- devServer:{
- // 开发服务器
- }
- }
JS 文件里引入:
require('@babel/polyfill')
至此, 可以打包 ES6 语法的文件了.
8. 加载图片, 音频等资源
以图片为例, 引入情况有三种:
CSS 中的背景图片
- body{
- background: url('./img/bg.jpg')
- }
JS 中通过创建 Image 标签再引入:
- import logo from './img/logo.jpg'
- let img = new Image()
- img.src = logo
在 HTML 标签中引入
<img src="./img/logo.jpg" alt="">
前两中情况, 需要安装:
NPM i url-loader file-loader -D
webpack.config.JS 加入:
- // ...
- module.exports = {
- // ...
- module: {
- rules: [
- // ...
- {
- test: /\.(PNG|jpe?g|gif|m4a)$/, // 加载 JS img 对象, CSS 中的图片, 音频等资源
- use: [
- {
- loader: 'url-loader',
- options: {
- // 资源大小小于等于 limit 值, 则会以 base64 形式加载, 不会发请求, 大于这个值则用 file-loader 加载
- limit: 200*1024
- }
- }
- ]
- }
- ]
- },
- plugins:[
- // 存放插件
- ],
- devServer:{
- // 开发服务器
- }
- }
在 HTML 标签中引入图片需要安装:
NPM i HTML-withimg-loader -D
webpack.config.JS 加入:
- // ...
- module.exports = {
- // ...
- module: {
- rules: [
- // ...
- {
- test: /\.HTML$/, // 加载 img 标签中的图片
- use: [
- {
- loader: 'html-withimg-loader',
- options: {}
- }
- ]
- }
- ]
- },
- plugins:[
- // 存放插件
- ],
- devServer:{
- // 开发服务器
- }
- }
汇总:
最后 webpack.config.JS 长这个样子:
- const path = require('path')
- const { CleanWebpackPlugin } = require('clean-webpack-plugin') // 自动清除沉余 JS
- const HtmlWebpackPlugin = require('html-webpack-plugin') // 自动生成 HTML 插件
- module.exports = {
- entry: './src/index.js', // 入口文件
- output: {
- filename: 'bundle.[hash].js', // 默认为 main.JS [hash]是为了避免 JS 缓存
- path: path.resolve(__dirname,'./dist') // path 为绝对路径, 用 node path 模块转化
- },
- mode: 'development', // 开发模式, 生产模式'production' 会压缩代码
- module: { // 加载 CSS Less
- rules: [
- {
- test: /\.CSS$/, // JS 中 require CSS
- use: ['style-loader','css-loader']
- },
- {
- test: /\.Less$/,
- // 注意顺序
- use: ['style-loader','css-loader','less-loader']
- },
- {
- test: /\.m?JS$/,
- exclude: /(node_modules|bower_components)/,
- use: {
- loader: 'babel-loader',
- options: {
- presets: ['@babel/preset-env'],
- plugins:[ // es6 内置函数转换
- '@babel/plugin-transform-runtime'
- ]
- }
- }
- },
- {
- test: /\.(PNG|jpe?g|gif|m4a)$/, // 加载 JS img 对象, CSS 中的图片, 音频等资源
- use: [
- {
- loader: 'url-loader',
- options: {
- // 图片大小小于等于 limit 值, 则会以 base64 形式加载, 不会发请求, 大于这个值则用 file-loader 加载
- limit: 200*1024
- }
- }
- ]
- },
- {
- test: /\.HTML$/, // 加载 img 标签中的图片
- use: [
- {
- loader: 'html-withimg-loader',
- options: {}
- }
- ]
- }
- ]
- },
- plugins:[ // 存放插件
- new HtmlWebpackPlugin({
- template: './src/index.html', // 模板
- filename: 'index.html', // 默认也是 index.HTML
- minify: {
- removeAttributeQuotes: true, // 删除标签属性的双引号
- collapseInlineTagWhitespace: true, // 删除多余空格
- },
- hash: true, // 增加 hash, 避免缓存
- }),
- new CleanWebpackPlugin()
- ],
- devServer:{ // 开发服务器配置
- port: 3000, // 端口号
- progress: true, // 进度条
- contentBase: './static', // 服务默认指向文件夹
- inline: true, // 设置为 true, 当源文件改变的时候会自动刷新
- historyApiFallback: true, // 在开发单页应用时非常有用, 它依赖于 HTML5 history API, 如果设置为 true, 所有的跳转将指向 index.HTML
- hot: true, // 允许热加载
- open: true // 自动打开浏览器
- }
- }
最后 package.JSON 长这个样子(变了的只有 scripts 部分, 配置脚本):
- {
- "name": "audio-player",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "build": "webpack --config webpack.config.js",
- "dev": "webpack-dev-server"
- },
- "author": "sparket",
- "license": "ISC",
- "devDependencies": {
- "@babel/core": "^7.6.0",
- "@babel/plugin-transform-runtime": "^7.6.0",
- "@babel/preset-env": "^7.6.0",
- "babel-loader": "^8.0.6",
- "clean-webpack-plugin": "^3.0.0",
- "css-loader": "^3.2.0",
- "html-webpack-plugin": "^3.2.0",
- "less": "^3.10.3",
- "less-loader": "^5.0.0",
- "style-loader": "^1.0.0",
- "webpack": "^4.40.2",
- "webpack-cli": "^3.3.9",
- "webpack-dev-server": "^3.8.1"
- },
- "dependencies": {
- "@babel/polyfill": "^7.6.0",
- "@babel/runtime": "^7.6.0",
- "file-loader": "^4.2.0",
- "html-withimg-loader": "^0.1.16",
- "url-loader": "^2.1.0"
- }
- }
安装的插件有:
- NPM i --D webpack webpack-cli clean-webpack-plugin HTML-webpack-plugin webpack-dev-server CSS-loader style-loader Less Less-loader babel-loader url-loader file-loader HTML-withimg-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime
- NPM i --save @babel/runtime @babel/polyfill
参考资料:
- https://www.jianshu.com/p/99675e491ee6
- https://www.jianshu.com/p/f06e901860e
- https://www.jianshu.com/p/bacc576979fe
来源: http://www.jianshu.com/p/681b76a4da95