Webpack教程:如何从头开始设置 webpack 5

  • 节点 polyfill 不再可用,例如,如果遇到stream错误,则可以将stream-browserify包作为依赖项添加,并将{stream:'stream-browserify'}添加到webpack配置中的alias属性。

什么是 webpack?


现在,大多数网站不再只是单单的由原生JS+纯HTML编写的,还涉及一些浏览器无法理解的语言,如果项目大,文件多,对应的体积就大。所以要压缩文件和翻译成所有浏览器都能理解的东西,这就是webpack的用武之地。

webpack 可以看做是模块打包器:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

对于开发,webpack 还提供了一个开发服务器,它可以在我们保存时动态地更新模块和样式。vue createcreate-response-app本质上都依赖于 webpack。

webpac k可以做很多事情,本文只是帮助大家熟悉一些主要概念并进行一些手动的配置。

安装


首先,创建一个目录webpack-tutorial,相关命令如下:

mkdir webpack-tutorial

cd webpack-tutorial

npm init -y // 创建默认的 package.json

安装webpackwebpack-cli

npm i -D webpack webpack-cli

接着,创建目录 src,并在其里面创建 index.js,内容如下:

console.log(‘Interesting!’)

基本配置


在项目的根目录中创建一个webpack.config.js

Entry

entry是配置模块的入口,可抽象成输入,Webpack 执行构建的第一步将从入口开始搜寻及递归解析出所有入口依赖的模块。

entry 配置是必填的,若不填则将导致 Webpack 报错退出。这里,我们将src/index.js做为入口点。

const path = require(‘path’)

module.exports = {

entry: {

main: path.resolve(__dirname, ‘./src/index.js’),

},

}

Output

配置 output 选项可以控制 webpack 如何向硬盘写入编译文件。注意,即使可以存在多个入口起点,但只指定一个输出配置。这里指定输出的路径为 ‘dist’:

module.exports = {

/* … */

output: {

path: path.resolve(__dirname, ‘./dist’),

filename: ‘[name].bundle.js’,

},

}

现在,我们具有构建捆绑包所需的最低配置。 在package.json中,我们可以创建一个运行webpack命令的构建脚本。

“scripts”: {

“build”: “webpack”

}

现在可以运行它了:

npm run build

现在在 dist 目录会生成一个 main.bundle.js 文件

插件


webpack有一个插件接口,这使得它更加灵活。内部webpack代码和第三方扩展使用插件,有一些主要的方法几乎每个webpack项目都会用到。

HTML 模板文件


目前,我们有一个随机的bundle文件,但它对我们还不是很有用。如果需要使用main.bundle.js,就要借助 HTML页面来加载这个 JS 包作为脚本。我们希望HTML文件自动引入这个生成 js 文件,所以我们将使用html-webpack-plugin创建一个HTML模板。

安装一下:

npm i -D html-webpack-plugin

src文件夹中创建一个template.html文件,这里,我们自定义一个title,内容如下:

src/template.html

<%= htmlWebpackPlugin.options.title %>

创建配置的plugins属性,然后将插件,文件名添加到输出(index.html),并链接到将基于该模板的模板文件。

const path = require(‘path’)

const HtmlWebpackPlugin = require(‘html-webpack-plugin’)

module.exports = {

/* … */

plugins: [

new HtmlWebpackPlugin({

title: ‘webpack Boilerplate’,

template: path.resolve(__dirname, ‘./src/template.html’), // template file

filename: ‘index.html’, // output file

}),

],

}

现在再次运行构建,会看到dist文件夹现在包含一个index.html,里面也自动引入了我们打包好的 js 文件。用浏览器打开 index.html,会在控制台看到 Interesting!

接着,在index.js中我们动态插入一些 dom 元素到页面中,内容如下:

// Create heading node

const heading = document.createElement(‘h1’)

heading.textContent = ‘Interesting!’

// Append heading node to the DOM

const app = document.querySelector(‘#root’)

app.append(heading)

重新构建,在进入 dist 目录下面,用 http-server 运行 html 文件。

http-server

可以在页面上看到,我们注入的 "Interesting!",还会注意到捆绑文件已缩小。

注意:在安装HtmlWebpackPlugin后,你会看到一个DeprecationWarning,因为插件在升级到webpack 5后还没有完全摆脱deprecation警告。

Clean


我们还需要设置clean-webpack-plugin,在每次构建后清除dist文件夹中的所有内容。 这对于确保不遗留任何旧数据很重要。

clean-webpack-plugin-删除/清理构建文件夹

const path = require(‘path’)

const HtmlWebpackPlugin = require(‘html-webpack-plugin’)

const {CleanWebpackPlugin} = require(‘clean-webpack-plugin’)

module.exports = {

/* … */

plugins: [

/* … */

new CleanWebpackPlugin(),

],

}

Modules and Loaders


webpack 使用 loader 预处理一些加载的文件,如 js 文件、静态资源(如图像和CSS样式)和编译器(如TypeScriptBabel)。webpack 5也有一些内置的资产加载器。

在我们的项目中,有一个HTML文件,该文件可以加载并引入一些 JS ,但实际上并没有执行任何操作。 那么这个webpack配置要做的主要事情是什么?

  • 将 JS 编译为浏览器可以理解的版本

  • 导入样式并将 SCSS 编译为 CSS

  • 导入图像和字体

  • (可选)设置React或Vue

Babel (JavaScript)


Babel是一个工具,可让使用最新的 JS 语法。

建立一个规则来检查项目中(node_modules之外)的任何.js文件,并使用babel-loader进行转换。 Babel 还有一些其他的依赖项:

  • babel-loader-使用 Babel 和 webpack 传输文件。

  • @babel/core-将ES2015+ 转换为向后兼容的 JavaScript

  • @babel/preset-env-Babel 的智能默认设置

  • @babel/plugin-proposal-class-properties-自定义 Babel 配置的示例(直接在类上使用属性)

npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-env @babel/plugin-proposal-class-properties

webpack.config.js

module.exports = {

/* … */

module: {

rules: [

// JavaScript

{

test: /.js$/,

exclude: /node_modules/,

use: [‘babel-loader’],

},

],

},

}

如果是 TypeScript 项目,使用的是typescript-loader而不是babel-loader

现在Babel已经设置好了,但是我们的Babel插件还没有。可以在index.js中添加一些新的语法来证明它还不能正常工作。

// 创建没有构造函数的类属性

class Game {

name = ‘Violin Charades’

}

const myGame = new Game()

// 创建 p 节点

const p = document.createElement(‘p’)

p.textContent = I like ${myGame.name}.

const heading = document.createElement(‘h1’)

heading.textContent = ‘Interesting!’

const app = document.querySelector(‘#root’)

app.append(heading, p)

要解决这个问题,只需在项目的根目录中创建一个.babelrc文件。可以使用preset-envplugin-proposal-class-properties添加更多默认值。

{

“presets”: [“@babel/preset-env”],

“plugins”: [“@babel/plugin-proposal-class-properties”]

}

现在运行npm run build 一切准备就绪。

Images


假设我们需要引用一张图片并直接导入到 JS 文件中,这样是无法正常工作的。 为了演示,创建 src/ images 并向其中添加图像,然后尝试将其导入到index.js文件中。

src/index.js

import example from ‘./images/example.png’

/* … */

运行构建时,再次看到错误:

webpack有一些内置的asset modules ,可用于静态资源。 对于图像类型,我们将使用asset/resource,注意,这里是一个type,而不是loader

webpack.config.js

module.exports = {

/* … */

module: {

rules: [

// Images

{

test: /.(?:ico|gif|png|jpg|jpeg)$/i,

type: ‘asset/resource’,

},

基础面试题

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

到 JS 文件中,这样是无法正常工作的。 为了演示,创建 src/ images 并向其中添加图像,然后尝试将其导入到index.js文件中。

src/index.js

import example from ‘./images/example.png’

/* … */

运行构建时,再次看到错误:

webpack有一些内置的asset modules ,可用于静态资源。 对于图像类型,我们将使用asset/resource,注意,这里是一个type,而不是loader

webpack.config.js

module.exports = {

/* … */

module: {

rules: [

// Images

{

test: /.(?:ico|gif|png|jpg|jpeg)$/i,

type: ‘asset/resource’,

},

基础面试题

主要内容包括:HTML,CSS,JavaScript,浏览器,性能优化等等

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值