webpack摸索笔记
1、先安装好node
2、建个项目文件
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。3,、window+r,打开终端 初始化这个项目
npm init -y
3.1、本地安装webpack(官方建议本地安装)
npm install --save-dev webpack
3.2、如果用webpack4+版本,还需要安装webpack-cli
npm install --save-dev webpack-cli
4、根目录下创建src/index.html 引入main.js 这个main.js不用创建,等会儿自己会生dist文件下成(奇怪),而且默认的入口文件是src下的index.js.
5、运行一下npx webpack,后,发现在dist文件下出现了main.js.都是大包过后的代码(奇怪)
4/5出现的奇怪现象,都是在未自定义配置文件时出现的情况,猜测是webpack4+版本将会默认设置一份配置文件,放在了我看不到的地方。
接下来我们设置自己的一个webpack配置文件,用来管理webpack打包
在跟目录下创建一个webpack.config.js文件
里面可以配置文件的入口,和出口!!!
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
以上代码表示,入口文件是index.js,出口文件是bundle.js,这个bunld.js文件同样不用自己创建,只要在这配置好了,打包命令执行后会自动创建;
切记将index.html中script标签引入的js由main.js该成bundle.js,因为现在的出口文件是bundle.js
现在,让我们通过新配置文件再次执行构建:
npx webpack --config webpack.config.js
NPM 脚本(NPM Scripts)
考虑到用 CLI 这种方式来运行本地的 webpack 不是特别方便,我们可以设置一个快捷方式。在 package.json 添加一个 npm 脚本(npm script):
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"dev":"webpack"
},
现在,可以使用 npm run dev
命令,来替代我们之前使用的 npx
命令。
加载 CSS
为了从 JavaScript 模块中 import
一个 CSS 文件,你需要在 module
配置中 安装并添加 style-loader 和 css-loader:
npm install --save-dev style-loader css-loader
webpack.config.js
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
在src下创建一个style.css文件,写上一下样式
在src下的index.js中通过import引入这个css
import './style.css';
运行一下打包命令npm run dev 发现样式生效了
加载图片
假想,现在我们正在下载 CSS,但是我们的背景和图标这些图片,要如何处理呢?使用 file-loader,我们可以轻松地将这些内容混合到 CSS 中:
在webpack.config.js文件的rules数组下,添加这一项配置
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
下载包
npm install --save-dev file-loader
在src下加一个名为icon的图片
在style.css里加一个背景样式,用上这个图片
在index.js文件里引入这张图
import Icon from './icon.png';
就可以在这个js里用这张图片了
执行一下打包命令npm run dev,就可以看到效果了!!!
加载字体
那么,像字体这样的其他资源如何处理呢?file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体。让我们更新 webpack.config.js
来处理字体文件:
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
在网上下载个字体文件加到src文件下,在style.css引入(这只是一个简单的引入方式)
@font-face {
font-family: 'webfont';
src:url('./fontname.ttf') format('truetype');
}
.hello {
color: red;
font-family: 'webfont' !important;
background: url('./icon.png') no-repeat;
}
打包运行 npm run dev会发现字体变了
加载数据
此外,可以加载的有用资源还有数据,如 JSON 文件,CSV、TSV 和 XML。类似于 NodeJS,JSON 支持实际上是内置的,也就是说 import Data from './data.json'
默认将正常运行。要导入 CSV、TSV 和 XML,你可以使用 csv-loader 和 xml-loader。让我们处理这三类文件:
npm install --save-dev csv-loader xml-loader
更改webpack.config.js文件
{
test: /\.(csv|tsv)$/,
use: [
'csv-loader'
]
},
{
test: /\.xml$/,
use: [
'xml-loader'
]
}
在src中加入xml文件(data.xml)
<?xml version="1.0" encoding="UTF-8"?> <note> <to>Mary</to> <from>John</from> <heading>Reminder</heading> <body>Call Cindy on Tuesday</body> </note>
在src/index.js里导入xml文件(其它的文件也可以导入)
import Data from './data.xml';
console.log(Data);
npm run dev 运行一下,会在页面的控制台看到xml文件内容
回退处理
为了更好的 往下探索,我需要将一下文件删除
/src
- |- data.xml
- |- my-font.woff
- |- my-font.woff2
- |- icon.png
- |- style.css
webpack.config.js的module模块删除
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [
- 'style-loader',
- 'css-loader'
- ]
- },
- {
- test: /\.(png|svg|jpg|gif)$/,
- use: [
- 'file-loader'
- ]
- },
- {
- test: /\.(woff|woff2|eot|ttf|otf)$/,
- use: [
- 'file-loader'
- ]
- },
- {
- test: /\.(csv|tsv)$/,
- use: [
- 'csv-loader'
- ]
- },
- {
- test: /\.xml$/,
- use: [
- 'xml-loader'
- ]
- }
- ]
- }
src/index.js 恢复到原来代码
import _ from 'lodash';
function component() {
var element = document.createElement('div');
element.innerHTML = _.join(['hello', 'world'], ' ');
return element;
}
document.body.appendChild(component());
管理输出
到目前为止,我们在 index.html
文件中手动引入所有资源,然而随着应用程序增长,并且一旦开始对文件名使用哈希(hash)]并输出多个 bundle,手动地对 index.html
文件进行管理,一切就会变得困难起来。然而,可以通过一些插件,会使这个过程更容易操控。
其实撸到这,自己就大致了解webpack的模式了,加插件,改配置。。。后面的大家可以自己撸了,奉上中文文档地址
想了想还是再写写吧,写理解与思路,不详细上代码了
我们可以将文件入口设置成多文件入口,(需要在webpack.config.js)里配置一下,
多文件入口配置好之后,dist文件中会生成对应的打包好的文件,我们之前是将这些打包好的文件固定名字引入index.html文件的,但是当我们新增入口文件,或改变入口文件名时,而index.html还是引用的原来的打包好得文件名,手动去改,势必会比较麻烦,所以我们需要借用HtmlWebpackPlugin插件来解决这个问题;
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/
文件夹我们已经有 index.html
这个文件,然而 HtmlWebpackPlugin
还是会默认生成 index.html
文件。这就是说,它会用新生成的 index.html
文件,把我们的原来的替换。(好高大上!!!!),这样我们无论新增还是更改入口文件的名字,这个新生成的index.html都会将打包好的js文件对应加载进去的。
清理 /dist
文件夹
我们每次执行打包命令,都会在dist文件下生成打包内容,看着很乱,所以在打包命令前,将dist文件清理一下,会让dist保存的都是有用文件;
构建开发环境
使用 source map
当 webpack 打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,如果将三个源文件(a.js
, b.js
和 c.js
)打包到一个 bundle(bundle.js
)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js
。这并通常没有太多帮助,因为你可能需要准确地知道错误来自于哪个源文件。
为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。如果一个错误来自于 b.js
,source map 就会明确的告诉你。
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
devtool: 'inline-source-map',
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
在print.js文件中生成一个错误(故意将console写错)
export default function printMe() {
cosnole.error('I get called from print.js!');
}
然后进行打包命令,打开index.html页面点击按钮,浏览器控制台会显示出错误在哪个js文件,这样就很好定位错误了;
选择一个开发工具(观察者模式)
每次要编译代码时,手动运行 npm run build
就会变得很麻烦
webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码,俗称观察者模式!!!(下面提供三种方法实现)
1、webpack's Watch Mode
2、webpack-dev-server
3、webpack-dev-middleware
多数场景中,你可能需要使用 webpack-dev-server
,但是不妨探讨一下以上的所有选项。
使用观察模式
你可以指示 webpack "watch" 依赖图中的所有文件以进行更改。如果其中一个文件被更新,代码将被重新编译,所以你不必手动运行整个构建。
我们添加一个用于启动 webpack 的观察模式的 npm script 脚本:
package.json文件
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"build": "webpack",
"dev": "webpack"
},
现在,你可以在命令行中运行 npm run watch
,就会看到 webpack 编译代码,然而却不会退出命令行。这是因为 script 脚本还在观察文件。
这时该一下print.js里的代码,不需要运行npm run dev只需要刷新一下页面,内容就变过来了,这就是watch模式。
使用 webpack-dev-server(经常使用)
webpack-dev-server
为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。让我们设置以下:
npm install --save-dev webpack-dev-server
修改配置文件,告诉开发服务器(dev server),在哪里查找文件:
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
devtool: 'inline-source-map',
devServer: { contentBase: './dist' },
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
以上配置告知 webpack-dev-server
,在 localhost:8080
下建立服务,将 dist
目录下的文件,作为可访问文件。
让我们添加一个 script 脚本,可以直接运行开发服务器(dev server):
package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
"build": "webpack",
"dev": "webpack"
},
现在,我们可以在命令行中运行 npm start
,就会看到浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。试一下!
会自动弹出一个url为localhost:8080的页面,此时更改任何一个代码,都会实时的反馈到页面上
使用 webpack-dev-middleware
ebpack-dev-middleware
是一个容器(wrapper),它可以把 webpack 处理后的文件传递给一个服务器(server)。 webpack-dev-server
在内部使用了它,同时,它也可以作为一个单独的包来使用,以便进行更多自定义设置来实现更多的需求。接下来是一个 webpack-dev-middleware 配合 express server 的示例。
首先,安装 express
和 webpack-dev-middleware
:
npm install --save-dev express webpack-dev-middleware
接下来我们需要对 webpack 的配置文件做一些调整,以确保中间件(middleware)功能能够正确启用:
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
},
plugins: [
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/'
}
};
publicPath
也会在服务器脚本用到,以确保文件资源能够在 http://localhost:3000
下正确访问,我们稍后再设置端口号。下一步就是设置我们自定义的 express
服务:
首先在根目录加一个server.js文件
内容是:
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
现在,添加一个 npm script,以使我们更方便地运行服务:
package.json
{
"name": "module",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"start": "webpack-dev-server --open",
"server": "node server.js",
"build": "webpack",
"dev": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^2.1.1",
"csv-loader": "^3.0.2",
"express": "^4.16.4",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"lodash": "^4.17.11",
"style-loader": "^0.23.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-middleware": "^3.6.2",
"webpack-dev-server": "^3.3.1",
"xml-loader": "^1.2.1"
},
"dependencies": {}
}
现在,在你的终端执行 npm run server
,将会启动这个服务器
现在,打开浏览器,跳转到 http://localhost:3000
,你应该看到你的webpack 应用程序已经运行!
调整文本编辑器
使用自动编译代码时,可能会在保存文件时遇到一些问题。某些编辑器具有“安全写入”功能,可能会影响重新编译。
要在一些常见的编辑器中禁用此功能,请查看以下列表:
- Sublime Text 3 - 在用户首选项(user preferences)中添加
atomic_save: "false"
。 - IntelliJ - 在首选项(preferences)中使用搜索,查找到 "safe write" 并且禁用它。
- Vim - 在设置(settings)中增加
:set backupcopy=yes
。 - WebStorm - 在
Preferences > Appearance & Behavior > System Settings
中取消选中 Use"safe write"
。
