以下是关于Udacity的Front End Web Developer课程的课程笔记,主要是记录一些主要命令和概念。
资源下载
复刻Udacity的一个webpack实例app到自己github仓库并克隆。命令:
git clone https://github.com/<Your Github Username>/fend-webpack-content.git
cd fend-webpack-content
git checkout 0-initial-setup
git branch
npm的安装与使用
查看node和npm的版本:
node -v
npm -v
将npm更新到最新版本:
npm install -g npm@latest
npm install
如果npm install
抛出错误,尝试清空缓存并重装:
npm cache clean
[sudo] npm install -g npm
npm install
如果需要修复漏洞,运行npm audit fix
使用npm run start
启动你的项目。
输入网址http://localhost:8080/查看你的网站,也可以在server.js中更改运行的端口。(更改端口node篇有提)
Webpack的安装
- 安装Webpack
npm i webpack webpack-cli
npm i
只是npm install
的缩写。CLI (command-line interface)是一个允许开发者通过在命令行运行命令与Webpack交流的终端程序。
- 运行后可以在package.json中看到
webpack
和webpack-cli
被加入“dependencies”:
"dependencies": {
"express": "^4.17.1",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
- 在
package.json
,添加一个build npm script(脚本),这是个npm脚本,用来运行webpack命令,你也可以自定义脚本:
"scripts": {
"build": "webpack"
},
最后加上:
"devDependencies":{
"webpack-dev-server": "^3.11.0",
},
- 在项目的根目录创建一个
webpack.config.js
文件,添加一个require语句和 空的module.exports 代码:
const path = require("path")
const webpack = require("webpack")
module.exports = {
}
//这时候运行会报错
关于Webpack Entry
webpack会为我们创建一个叫做“依赖关系树”的东西,依赖关系树从一个文件开始,随着webpack浏览过该文件,它会查找这一文件所需的其他依赖项,假设这个文件是一个javascript文件,其中使用了一个来自其他文件的函数,当webpack发现需要另外一个文件时,它会跳转到那个需要的文件,浏览一遍,如果在那个文件中找到更多依赖项,再跳转到运行该文件所必需的每个依赖项,以此类推构建出我们所说的“依赖关系树”。
要构建这个依赖关系树,webpack就需要一个起点,叫做Entry。
webpack自己会默认的设置入口(./src/index.js),但是由于我们使用express改变了项目的目录结构,src中并不存在index.js, 因此需要将entry替换成对应的路径。
index.js中的内容如下:
alert("I EXIST")
打开webpack.config.js
,设置module.exports:
module.exports = {
entry: './src/client/index.js'
}
然后运行npm run build
,完成后会发现根目录多了一个dist(distribution)文件夹,这是webpack生成的。
dist文件夹
dist是distribution的缩写,表示分发,与源文件夹src并列。这两个文件夹都十分重要。源文件夹包含所有你需要编辑的文件,分发文件夹是负责网页运行时的分发。因此用户正在运行的网站引用的是分发文件夹而不是源文件。每一次运行,分发文件夹都会重新生成,因此如果你想永久改变文件内容比如一个按钮的css样式,应该在源文件夹改,如果您想快速看到效果可以在分发文件夹中进行尝试。
现在,可以将dist文件夹下的main.js文件引入index.html,并删除其他引用了。
现在我们要在index.js中引入其他js文件,让他们形成联系。由于我们在浏览器端,不能使用require,要引用文件,首先要安装babel。
Babel的安装与使用
Babel是一个专用工具,能进行Javascript的版本切换,我们可以借助它运行ES6,它可以将所有新语法翻译成浏览器可以识别的预防,这样即使浏览器还没有提供支持,也可以使用更新版本的javascript语法。
- 安装Babel
npm i -D @babel/core @babel/preset-env babel-loader
-D意味着将其安装到开发环境中,这意味着现在安装的所有软件包不是用于应用的生产环境,仅在开发过程中可用,不需要在向用户提供应用服务时出现。
2.在根目录创建一个新文件.babelrc
,输入:
{ ‘presets’: ['@babel/preset-env'] }
如果需要其他配置,可以阅读babel提供的文档
loader
现在可以在index.js中引入其他js文件了。
首先要export你需要的文件中的函数,然后才能使用import导入。
回到webpack配置文件,在其中添加rules:
module.exports = {
entry: "./src/client/index.js",
module: {
rules: [
{
//正则表达式,匹配以js结尾的文件
test: "/.js$/",
//定目录下的文件不被加载器使用
exclude: /node_modules/,
//加载器,是在安装babel的过程中安装的
loader: "babel-loader",
},
],
},
};
javascript用加载器和插件(plugin)来实现所有资源的打包。
当webpack形成依赖关系树时,依赖关系树中会有很多不同类型的文件,这里的意思是,所有js资源文件需要通过这个特定加载器进行处理。
之后再运行,会看到index.js和formHandler.js都添加到了main.js文件中,他们都是分发文件夹的一部分。
loader使用实例
加载器允许我们将一种类型的文件转换为另一种类型,以便WebPack可以与它们一起工作。
下面根据官方文档来使用一下file-loader:
- 安装file-loader:
npm install file-loader --save-dev
- 在index.js中引入图片,并更新webpack配置文件:
import img1 from './img/img1.jpg'
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
- 然后运行,就可以看到img1.jpg也出现在main.js中了。
plugins插件
webpack是这样描述plugin的:
While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables.
html-webpack-pulgin
html-webpack-pulgin的功能是使webpack动态添加dist文件夹的引用。
- 安装插件:
npm i -D html-webpack-plugin
- 在webpack配置文件中添加对node_modules目录中html-webpack-plugin插件的引用。
const HtmlWebPackPlugin = require("html-webpack-plugin")
- 在module.exports中添加一个plugins:
plugins: [
new HtmlWebPackPlugin({
template: "./src/client/views/index.html",
filename: "./index.html",
})
]
- 然后运行,我们会发现dist中多了一个文件index.html,这个文件动态引入了main.js文件
- 打开
server/index.js
,将res.sendFile('/cilent/views/index.html')
改为res.sendFile('dist/index.html')
,这是express查找用来生成页面的文件。 - 将
app.use(express.static('src/client'))
改为app.use(express.static('dist'))
mode
在运行过程中,我们经常会看到关于配置的warning:
这是因为我们没有告诉webpack我们处于什么样的模式(生产、开发、或测试)。
生产(production)环境和开发(development)环境
开发者将一个网站的各种状态叫做环境,当我们开发一个网站时,就是开发环境,我们在localhost上运行服务器。
另一方面,我们在服务器上运行代码,调试每一个工具和文件以优化效率,希望给用户最好的体验,这是生产环境。
对于一个项目,还会有测试环境、审查环境等,这里只关注生产环境和开发环境。
有很多工具旨在让开发人员更轻松地编写代码。其中一个称为“sass”的工具,它是具有一些对开发人员很友好的语法和特性的CSS。我们有让开发变得更容易的工具,但以sass为例-我们不能在服务器上运行sass。所有的sass文件都必须通过transpiler才能变成可以运行在网页上的css。无论开发工具有多棒,我们的代码最终都将根据它在服务器上的运行情况来判断,而且通常对服务器最好的东西与对开发人员方便的东西是相反的。那么,我们如何处理这两种环境呢?通过利用构建工具,我们可以编写对我们的开发团队来说方便的代码,而不会牺牲服务器的速度。
Webpack令人敬畏的特性之一是,它允许我们根据运行的环境将配置应用到我们的代码。我们可以创建一个开发环境(webpack中的模式),运行与生产模式完全不同的加载器和插件。
设置mode
- 复制一份
webpack.config.js
,将其重命名为webpack.prod.js
,prod代表的是production,这是生产环境的配置文件。在module.exports
中输入:
mode: 'production'
- 将
webpack.config.js
重命名为webpack.dev.js
,这是开发环境的配置文件。
在module.exports
中输入:
mode: 'development',
devtool: 'source-map',
- 在
package.json
中,有一个通用的构建命令"build": "webpack"
,将其替换为:
"build-prod": "webpack --config webpack.prod.js",
"build-dev": "webpack --config webpack.dev.js"
4.然后输入npm run build-dev
或npm run build-prod
就能运行不同的模式了。
Webpack Dev Server的安装与使用
Webpack Dev Server允许创建只针对开发模式的服务器,使你可以立即运行文件并及时更新。
webpack提供监视(watch)特定文件的能力,可以侦测到文件发生的更改,watch可以直接添加到命令参数中:
"build-dev": "webpack --config webpack.dev.js --watch --info-verbosity verborse"
然后运行,你会发现webpack会一直监视文件更改,并重新运行对所有文件的编译。但是你仍需要自己刷新浏览器来看到变化。
这时,就可以使用webpack Dev sever,它支持很受欢迎的热重载功能,比如react中很好用的-对文件进行更改浏览器也会实时刷新。
- 安装
npm i -D webpack-dev-server
- 编辑build-dev脚本,将其替换为:
"build-dev": "webpack-dev-server --config webpack.dev.js --open"
这个语句告诉webpack 使用开发服务器来运行webpack开发配置文件,并且每次运行时都要自动打开浏览器(–open)
一些好用的小插件安装
clean
每次重新运行脚本时,都要先删除dist文件夹,因为wepack不会自动删除旧的文件,因此可以安装clean-webpack-plugin
- 安装:
npm i -D clean-webpack-plugin
- 在配置文件中加入:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
- 在插件数组中加入:
new CleanWebpackPlugin({
// Simulate the removal of files
dry: true,
// Write Logs to Console
verbose: true,
// Automatically remove all unused webpack assets on rebuild
cleanStaleWebpackAssets: true,
protectWebpackAssets: false
})
如果没有加入参数,plugin会运行默认设置。
Webpack Bundle Analyzer
安装命令:
# NPM
npm install --save-dev webpack-bundle-analyzer
作为插件使用:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}
这个插件将创建所有捆绑包内容的交互式树状图可视化。
可以帮助你
- 意识到你的bundle中有什么
- 找到哪些模块构成了其最大的部分
- 找到出错的模块
- 优化它!
- 具体文档看这里
其他资源链接
Multiple entry points with webpack
Using webpack to be more efficient with your styles and assets
Helpful official documentation(guides 和 concepts都可以看看)