一、webpack是什么?
webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。
二、安装
前提条件:
确保安装了Node.js的最新版本。(旧版本可能遇到各种问题)
本地安装:
要安装最新版本或特定版本,请运行以下命令之一:
npm install --save-dev webpack
npm install --save-dev webpack@<version>
如果你使用 webpack 4+ 版本,你还需要安装 CLI。
npm install --save-dev webpack-cli
对于大多数项目,我们建议本地安装。这可以让我们在引入破坏式变更的依赖时,更容易分别升级项目。
全局安装:
以下的 NPM 安装方式,将使 webpack
在全局环境下可用:
npm install --global webpack
不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。
最新体验版本:
npm install webpack@beta
npm install webpack/webpack#<tagname/branchname>
安装这些最新体验版本时要小心!它们可能仍然包含 bug,因此不应该用于生产环境。
三、起步
创建目录,初始化npm,并安装webpack和webpack-cli:
mkdir webpack-demo && cd webpack-demo npm init -y npm install webpack webpack-cli --save-dev
现在我们将创建以下目录结构、文件和内容:
project
webpack-demo |- package.json + |- index.html + |- /src + |- index.js
src/index.js
function component() { var element = document.createElement('div'); // Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的 element.innerHTML = _.join(['Hello', 'webpack'], ' '); return element; } document.body.appendChild(component());
index.html
<!doctype html> <html> <head> <title>起步</title> <script src="https://unpkg.com/lodash@4.16.6"></script> </head> <body> <script src="./src/index.js"></script> </body> </html>
另外我们还需要调整pageage.json文件,以便确保我们安装包是私有的(private)
,并且移除 main
入口。这可以防止意外发布你的代码。
package.json
{ "name": "webpack-demo", "version": "1.0.0", "description": "", + "private": true,//确保是私有的 - "main": "index.js",//移除,可以防止意外发布你的代码 "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.0.1", "webpack-cli": "^2.0.9" }, "dependencies": {} }
创建一个bundle文件:
首先,我们稍微调整下目录结构,将“源”代码(/src
)从我们的“分发”代码(/dist
)中分离出来
project
webpack-demo |- package.json + |- /dist + |- index.html - |- index.html |- /src |- index.js
要在 index.js
中打包 lodash
依赖,我们需要在本地安装 library:
npm install --save lodash
如果要安装一个打包到生产环境的安装包,应该使用npm install --save;安装一个打包到开发环境的安装包,应该使用:npm install --save-dev。
现在,在我们的脚本中 import lodash:
src/index.js
import _ from 'lodash';
因为现在是通过 import
引入 lodash,所以将 lodash <script>
删除,然后修改另一个 <script>
标签来加载 bundle,而不是原始的 /src
文件:
dist/index.html
<!doctype html> <html> <head> <title>起步</title> - <script src="https://unpkg.com/lodash@4.16.6"></script> </head> <body> - <script src="./src/index.js"></script> + <script src="main.js"></script> </body> </html>
修改完成之后,执行 npx webpack,我们的脚本将作为入口起点,然后输出为main.js。
在浏览器中打开 index.html
,如果一切访问都正常,说明构建成功。
使用一个配置文件:
在webpack 4 中,可以无需任何配置,但是大多数项目需要更复杂的配置,这就是为什么webpack需要支持配置文件;这比在终端(terminal)中手动输入大量命令要高效的多,所以让我们创建一个取代以上使用 CLI 选项方式的配置文件:
project
webpack-demo |- package.json + |- webpack.config.js |- /dist |- index.html |- /src |- index.js
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } };
现在,让我们通过新配置文件再次执行构建:
npx webpack --config webpack.config.js
如果 webpack.config.js
存在,则 webpack
命令将默认选择使用它。我们在这里使用 --config
选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用。
npm脚本:
如果 webpack.config.js
存在,则 webpack
命令将默认选择使用它。我们在这里使用 --config
选项只是向你表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用。所以我们可以设置一种快捷方式(添加一个npm脚本):
package.json
{ "name": "webpack-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", + "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.0.1", "webpack-cli": "^2.0.9", "lodash": "^4.17.5" } }
现在,可以使用 npm run build
命令,来替代我们之前使用的 npx
命令。
现在运行以下命令,然后看看你的脚本别名是否正常运行:
npm run build
结论:
到此,我们就实现了一个基本的构建过程,目录结构如下:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src |- index.js |- /node_modules
如果你使用的是 npm 5,你可能还会在目录中看到一个 package-lock.json
文件。
四、管理资源
在 webpack 出现之前,前端开发人员会使用 grunt 和 gulp 等工具来处理资源。
加载css
安装并添加 style-loader 和 css-loader):
npm install --save-dev style-loader css-loader
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, + module: { + rules: [ + { + test: /.css$/, + use: [ + 'style-loader', + 'css-loader' + ] + } + ] + } };
加载图片
npm install --save-dev file-loader
{ test:/.(png|svg|jpg|gif)$/, use:[ 'file-loader' ] },
加载字体
file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。
{ test:/.(woff|woff2|eot|ttf|otf)$/, use:[ 'file-loader' ] },
加载数据
npm install --save-dev csv-loader xml-loader
{ test:/.(csv|tsv)$/, use:[ 'csv-loader' ] }, { test:/.xml$/, use:[ 'xml-loader' ] },
五、管理输出
管理bundle依赖
html-webpack-plugin可以自动给html添加bundle文件
npm install --save-dev html-webpack-plugin
webpack.config.js
const path = require('path'); + const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, + plugins: [ + new HtmlWebpackPlugin({ + title: 'Output Management' + }) + ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
清理dist文件夹
npm install clean-webpack-plugin --save-dev
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); + const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, plugins: [ + new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: 'Output Management' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };