在GitHub上发现的学习webpack和react的很好的文章,
原文链接
通过看前两篇文章你可能对Webpack有了一些了解,它是一个模块购建工具,可以打包你的文件.
听起来容易,实际上却不简单,我们都不想自已处理所有细节,这正是webpack要做的,接下来,将配置我们Webpack的第一个工程,并运行它在开发模式.
Webpack依赖于Node.js. 请确让你已装安装了它,并可以在你的命令行中运行
npm
命令. 建立一个目录用来放置你的工程, 进入到目录中,运行
npm init
, 并按提示填写信息,或者全部回车使用默任设置.
mkdir kanban_app
cd kanban_app
npm init -y
在你工程的目录下将会生成
package.json
文件,你可以打开它来进一步的配置你的工程.下面会主要使用
npm
这个工具,但是还是建议大家学一下
package.json
中的另种选项用法.
安装Git
安装Webpack
下一步, 我们安装Webpack, 我们使用局部安装并把它保存为工程依赖,这有利于针对每个工程,维护Webpack的版本. 执行
---
npm维护由它安装的可执行包的目录,你能使用
npm bin
命令显示这个具体的目录,很可能是
.../node_modules/.bin
。试一下在命令行中运行
node_modules/.bin/webpack
命令 或
node_modules\.bin\webpack
在windows。
之后你会看到打印出的有版本信息,和一些可用的选项。
kanban_app $ node_modules/.bin/webpack
webpack 1.12.12
Usage: https://webpack.github.io/docs/cli.html
Options:
--help, -h, -?
--config
--context
--entry
--display-cached-assets
--display-reasons, --verbose, -v
Output filename not configured.
Webpack使用全局安装(安装时指定-g或-global),而不是使用它安装为项目的依赖,这样你可以直接控制运行的版本,它不依赖于单独的工程,你可以在任何地方使用它。
我们使用
--save
和
--save-dev
区分应用环境依赖和开发环境依赖,前者将安装到
package.json
的
dependencies
节点,而后者将写到
devDependencies
节点。这种分离使得项目依赖关系更容易理解,最后打包时将不会打包
devDependencies
所包含的包。
现在的项目只有package.json看起来很low,我们将配置更多的具体的东西. 我们将实现一个小的web站点,并加载一些些JavaScript,然后使用Webpack进行构建. 要开始的话,请配置我们的目录结构如下.
/build
package.json
webpack.config.js
我们将使用Webpack,基于
/app
生成
bundle.js
,为了做的这一点,我们应该设置一些资源和
webpack.config.js
.
我们喜欢
Hello world
,所以我们创建一个这个模块.
app/component.js
module.exports = function () {
var element = document.createElement('h1');
element.innerHTML = 'Hello world';
return element;
接下来,我们需要一个我们应用的入口点. 用require加载我们的组件并渲染它到一个DOM:
app/index.js
var component = require('./component');
var app = document.createElement('div');
document.body.appendChild(app);
app.appendChild(component());
我们还需要一些HTML,用来加载我们上面的最终生成的bundle.js
build/index.html
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>Kanban app</title>
</head>
<div id="app"></div>
<script src="./bundle.js"></script>
</body>
</html>
Webpack配置文件
我们需要告诉Webpack怎么处理我们刚刚建立的资源.这些需要在webpack.config.js中配置.
webpack.config.js
const path = require('path');
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'build')
module.exports = {
// Entry accepts a path or an object of entries. We'll be using the
// latter form given it's convenient with more complex configurations.
entry: {
app: PATHS.app
output: {
path: PATHS.build,
filename: 'bundle.js'
上面的entry使用相对路径. 这个context字段,能用来配置绝对路径,考虑到很多地方需要绝对路径,我更喜欢使用绝对路径避免产生混淆.
我想使用path.join,但path.resolve是一个更好的选择.path.resolve等介于通过cd命令进行导航. 而path.join只是给你一个链接.详细信息请看 Node.js path API .
当我们调用 node_modules/.bin/webpack, 将会看到如下输出信息:
Hash: e7dd4bf8a294b5c93141
Version: webpack 1.12.11
Time: 734ms
Asset Size Chunks Chunk Names
bundle.js 12 kB 0 [emitted] main
[0] ./app/index.js 169 bytes {0} [built]
[5] ./app/component.js 136 bytes {0} [built]
+ 4 hidden modules
它意思是构建你的输出目录,使用浏览器打开build/index.html文件查看例子.
增加构建脚本
考虑到每次执行node_modules/.bin/webpack有些麻烦,我们需要做些什么,通过npm和package.json控制程序运转.
package.json
"scripts": {
"build": "webpack"
可以通过执行npm run 的方式运行脚本.尝试调用npm run build你会得到和之前相同的结果.
之所以"build": "webpack"没有配全路径,是因为npm会附加node_modules/.bin这个路径到运行时路径,即相当于配置"build": "node_modules/.bin/webpack". 还有一总可能是使用全局安装Webpack,但这样是有潜在危险的,它不利于我们对每个工程进行版本控制.
还能做的更好一些, 通过Grunt或者Gulp运行任务,可以达到相同的操作,并且是跨平台的. 但我们现在只是菜鸟,让我们keep things simple,暂时不去考虑它们.
配置开发服务器 webpack-dev-server
通过构建脚本开发你的应用程序,让人提不起劲,Webpack提供了一个更好的开发方式,通过webpack-dev-server这个运行在内存中的服务器,你在开发应用时它会自动刷新你的内容.它很像LiveReload或者Browsersync这些工具.
Webpack拥有这些工具最大的好处是模块热插拔(HMR), 总之,它提供了一总修补方式,不会完成刷新浏览器状态. 我们将会在学习React时详细讨论它.
你应该只是在开发时使用webpack-dev-server,如果是正式的应用考虑一个其它的成熟的解决方案,如Apache或Nginx.
要想开始webpack-dev-server,需要在跟目录下执行.
npm i webpack-dev-server --save-dev
就像上面, 我们在package.json中的scripts定义一个入口点.考虑到index.html在build目录下面,我们配置webpack-dev-server
基于这个目录.改变我们的package.json.
package.json
"scripts": {
"build": "webpack",
"start": "webpack-dev-server --content-base build"
现在你执行npm run start或npm start,你应该会在命令行中看到这些信息:
> webpack-dev-server
http://localhost:8080/
webpack result is served from /
content is served from .../kanban_app/build
404s will fallback to /index.html
webpack: bundle is now VALID.
意思是,服务器已经运行起来了.如果在浏览器中打开http://localhost:8080/,你应该看到Hello World,如果你修改你的代码,你应该能在终端看到一些信息.问题是我们还是得需要手动刷新才能看到改动结果. 这是我们接下来需要解决的.
作为开发设置有它自已的某些需求, 我们需要分离我们的Webpack配置文件.鉴于Webpack的配置全部是JavaScript的,所以我们有多种发式达到这个目地,至少以下的方式是可行的:
我更喜欢最后的方式,因为它让我可以知道发生了什么,非常适合小型项目.
To Keep things simple, 我已经定义了一个merge函数,连接数组和合并对象,我们马上就会知道,这在Webpack中是很方便的, 执行
npm i webpack-merge
将它加入到工程中.
接下来,我们需要定义一些分离点到我们的配置,自定义它在每个npm脚本.例如:
webpack.config.js
const merge = require('webpack-merge');
const TARGET = process.env.npm_lifecycle_event;
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'build')
module.exports = {
const common = {
// Entry accepts a path or an object of entries. We'll be using the
// latter form given it's convenient with more complex configurations.
entry: {
app: PATHS.app
output: {
path: PATHS.build,
filename: 'bundle.js'
// Default configuration
if(TARGET === 'start' || !TARGET) {
module.exports = merge(common, {});
if(TARGET === 'build') {
module.exports = merge(common, {});
现在我们可以进行扩展了,我们能连接到模块热插拔使浏览器刷新,这对开发是有帮助的.
配置模块热插拔(HMR)
HMR可以当我们做出改变时自动刷新浏览器, 我们想法是如果我们改变了 app/component.js,浏览器将自动刷新,同样适用于CSS的改变.
我了使它工作.我们需要连接到开发服务器,运行在内存中打包.Webpack使用基于WebSocket通信方式来达到这个目地. 我们让Webpack通过开发服务器的inline选项,来生成客户端部分,这个选项包含客户端需要的由HMR到Webpack生成的包的脚本.
webpack.config.js
leanpub-start-insert
const webpack = require('webpack');
leanpub-end-insert
if(TARGET === 'start' || !TARGET) {
leanpub-start-delete
module.exports = merge(common, {});
leanpub-end-delete
leanpub-start-insert
module.exports = merge(common, {
devServer: {
contentBase: PATHS.build,
// Enable history API fallback so HTML5 History API based
// routing works. This is a good default that will come
// in handy in more complicated setups.
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
// Display only errors to reduce the amount of output.
stats: 'errors-only',
// Parse host and port from env so this is easy to customize.
// If you use Vagrant or Cloud9, set
// host: process.env.HOST || '0.0.0.0';
// 0.0.0.0 is available to all network devices unlike default
// localhost
host: process.env.HOST,
port: process.env.PORT
plugins: [
new webpack.HotModuleReplacementPlugin()
leanpub-end-insert
鉴于我们在配置文件中配置了contentBase,故我们在package.json中移除它.
package.json
"scripts": {
"build": "webpack"
leanpub-start-delete
"start": "webpack-dev-server --content-base build"
leanpub-end-delete
leanpub-start-insert
"start": "webpack-dev-server"
leanpub-end-insert
执行 npm start并转到localhost:8080,尝试一下修改app/component.js,会发现浏览器跟着刷新.注意当你修改JavaScript代码,这是硬刷新,CSS变动在更加友好的方式,可以不刷新应用.在下一章我们研究怎样在React中实现类似的事情,这将提供我们更好的开发经验.
如果你想改变默认端口,可以配置process.env.PORT || 3000.
HMR on Windows
CSS 刷新
我们可以扩展这个方式对于CSS.Webpack允许我们改变CSS时不会强制完全刷新. 加载CSS到工程中,我们需要使用一对加载器.首先,调用:
npm i css-loader style-loader --save-dev
现在我们加载了需要的.我们还要确保Webpack知道它们.配置:
webpack.config.js
const common = {
leanpub-start-delete
leanpub-end-delete
leanpub-start-insert
module: {
loaders: [
// Test expects a RegExp! Note the slashes!
test: /\.css$/,
loaders: ['style', 'css'],
// Include accepts either a path or an array of paths.
include: PATHS.app
leanpub-end-insert
这个配置指的是以.css结尾的文件应该调用给定的加载器.test是JavaScript匹配样式文件的正则表达式.加载器是从右到左的顺序执行的.即先执行css-loader,然后执行style-loader. css-loader将处理我们CSS文件中的@import和url语句.style-loader在我们的JavaScript中的require语句.对CSS的预处理,像Sass和Less,并且加载它们.
设置初始CSS
我们为程序增加一点儿CSS:
app/main.css
body {
background: cornsilk;
此外我们需要让Webpack知道到它.没有require指向它,Webpack将不能找到这个文件.
app/index.js
leanpub-start-insert
require('./main.css');
leanpub-end-insert
执行npm start,并打开你的浏览器到localhost:8080.
试着改变main.css 例如background: lime使得它看起来漂亮一些.
加入 Sourcemaps
为了提高debug的能力.我们能配置一个sourcemaps.它能让我们看到错误的准确位置.在Webpack是通过devtool来设置的.
webpack.config.js
if(TARGET === 'start' || !TARGET) {
module.exports = merge(common, {
leanpub-start-insert
devtool: 'eval-source-map',
leanpub-end-insert
如果你运行npm start.Webpack将生成sourcemaps.Webpack支持多种不同的生成方式.详细请看官方文档.在上面的例子里,我们使用eval-source-map.它起初构建很慢.但是它支持快速重建和得到直实的文件.
更快速的开发指定选项,如cheap-module-eval-source-map 和 eval,生成低质量的sourcemaps.所有eval选项将把sourcemaps作为你JavaScript代码的一部分,因此,他们并不适合生产环境.但在开发过程中,往往是适合的用例.
有可能你需要在你的浏览器中启用sourcemaps选项.
使用npm-install-webpack-plugin避免npm install
为了避免一些输入,我们可以设置一个Webpack插件npm-install-webpack-plugin.随着我们的发展项目,它将检测到 Webpack 配置和项目文件所做的更改并为我们安装依赖项.它将自动修改package.json.
在这章学习了,我们学习了使用Webpack进行构建和开发.当前的配置是为了更好的开发而不是用于生产环境.下一章我们将应用到React中.
在GitHub上发现的学习webpack和react的很好的文章,原文链接通过看前两篇文章你可能对Webpack有了一些了解,它是一个模块购建工具,可以打包你的文件.听起来容易,实际上却不简单,我们都不想自已处理所有细节,这正是webpack要做的,接下来,将配置我们Webpack的第一个工程,并运行它在开发模式.建立工程Webpack依赖于Node.js. 请确让你已装安装了它,并可以在你的命令行
1.安装node-v-12.41.1-64.mis(可以再任何位置,安装时都默认)
2.在管理员身份cmd中输入node -v看见版本号则安装成功
3.下载插件npm install -g cnpm --registry=https://registry.npm.taobao.org
这是不用翻墙的插件(虚拟环境) 输入npm -v出现版本号则安装成功
4.cnpm install -g webpack
5.cnpm install -g vue-cli
6.cnpm instal
momopic@0.1.0 dev:mp-weixin D:\桌面\momopic
ERROR Failed to compile with 1 errors 9:11:48 ├F10: AM┤
This dependency was no
Project is running at ...
webpack output is served from
Content not from webpack is served from ...
404s will fallback to /
Starting the development server...
网上的说法很多,但是经笔者亲身经历之后,发现其实是电脑本身配置的问题,下面列出具体的修改方案:
1.右击我的电脑 ==>...
Vite.js 和 Webpack 都是现代 JavaScript 应用程序的构建工具,它们的共同目标是将应用程序源代码转换为可部署的 JavaScript、HTML 和 CSS。但是它们之间存在一些关键区别,包括以下几点:
1. 构建方式
Vite.js 是一种“零配置”构建工具,使用 Rollup 进行快速的开发环境构建,同时支持基于插件的定制。在开发模式下,Vite.js 使用 ES modules 来直接引入模块,而不是打包所有代码,因此启动时间非常快。在生产模式下,Vite.js 会对所有模块进行打包和压缩。
Webpack 则需要一个配置文件来定义如何构建应用程序。Webpack 支持插件和 loader,可以通过这些扩展来实现各种不同的构建需求,但是需要花费时间来学习和配置。Webpack 在开发模式下会将所有代码打包到一个或多个 JavaScript 文件中,并支持热模块替换。在生产模式下,Webpack 会对所有代码进行打包、优化和压缩。
2. 开发体验
Vite.js 在开发环境下启动速度快,因为它不需要打包所有代码。此外,Vite.js 还支持热模块替换(HMR),可以在不刷新浏览器的情况下更新代码。这使得开发体验非常流畅,并且可以大大减少开发周期。
Webpack 在开发环境下的启动时间可能较长,因为需要打包所有代码。但是,Webpack 也支持热模块替换(HMR),可以在不刷新浏览器的情况下更新代码。Webpack 还支持 source map 和代码分割,使得调试和优化非常方便。
3. 功能
Vite.js 和 Webpack 都支持常见的构建功能,例如代码压缩、打包和优化。但是它们的重点略有不同。
Vite.js 的重点是快速的开发环境和热模块替换(HMR),以及支持 Vue.js、React 和原生 ES modules 的构建。
Webpack 的重点在于强大的扩展性,可以通过 loader 和插件实现各种不同的构建需求。Webpack 还支持代码分割、tree shaking 和模块懒加载等高级功能,以及对各种模块类型的支持。
总的来说,Vite.js 和 Webpack 都是优秀的构建工具,可以根据具体需求来选择使用。如果你需要一个快速启动的开发环境和支持热模块替换的构建工具,那么 Vite.js 是一个很好的选择。如果你需要更强大的