时隔一年,我又回来了。近期给团队的小伙伴分享webpack知识,也在此留印一下。
我们用webpage做什么?
打包项目,编译代码、本地开发
webpack在项目里怎么被启动的?
在我们的package.json里面的script的指令,我们会对应一条命令
"scripts": {
"start": "./node_modules/.bin/webpack-dev-server --config ./webpack.config.js --port=9090 --DEV=1 --LIVELOAD=1",
"build": "./node_modules/.bin/webpack --config ./webpack.config.js"
}
npm start去执行了一个webpack-dev-server的命令并带了一些参数进去
-
为什么是执行./node_modules/.bin/...?
可能你会有这个疑问,我下载了全局的webpack,为什么要执行node_modules里面的webpack
是因为每个项目可能所对应的webpack版本不一样,以免发生跨版本的错误,所以会执行自己目录里依赖的包
-
什么是webpack-dev-server?
字面意思就是在开发环境起服务,这里不细说。webpack-dev-server文档
-
什么是--config?
我说一些常用的命令
--config 指定配置文件 --watch 文件更新时自动构建 --display-modules 构建时显示信息(耗时等) --port 指定启动端口 --mode 告知 webpack 使用相应模式的内置优化。 --自定义参数 可以在自己的配置文件取到
前戏
我们通过--config参数指定了我们自定义的配置文件 webpack.config.js,我们现在开始编写它
首先,webpack就接收一个对象,里面配置对应字段和规则就可以了!
module.exports = {
// 入口
entry: {},
// 出口
output: {},
}
如何执行它,就要看package里的命令怎么写。
还有!先下载依赖 webpack webpack-cli
开始
第一步:执行命令
"build": "./node_modules/.bin/webpack --config ./webpack.config.js --mode=production"
第二步:编写webpack.config.js
module.exports = {
entry: {
"index": path.resolve(__dirname, './index.js')
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
},
}
第三步:npm run build
你会发现,webpack已经开始工作了。它把我们写好的index.js打包到了./dist/index.js这里
卧槽,这就完成了,可以跑起来了。
你会问,为什么我只是简单写了入口出口,它就可以自己给我压缩混淆代码了???
注意看你package上的build命令,带了什么参数!--mode=production 这个参数是告诉webpack用哪种模式的内置优化,我们选择的是生产环境,那么它就会帮我们压缩混淆代码,反之,我们选择development 开发模式的话,它只会帮我编译打包代码
相信到这里大家会对webpack的了解会清晰一些了。那么下面我们继续再进阶到我们真实项目场景里面
进阶 (入门级进阶)
先看需求:
- 我要npm start自动开启浏览器,进入开发态
- 我要编译React
- 我要编译less
- 我要npm run build 打包整个项目
接着上面的Demo我们来增加一些配置就可以了
1. 我要npm start自动开启浏览器,进入开发态
这个需求的工作逻辑是,先启动一个服务,然后打开浏览器,去到对应的地址!
通过网上查阅资料,我们得知
- 启动服务用:webpack-dev-server
- 打开浏览器用:open-browser-webpack-plugin
先下载依赖,我们把package中的start命令改成去执行webpack-dev-server
"start": "./node_modules/.bin/webpack-dev-server --config ./webpack.config.js --port=8801"
然后进去webpack.config.js增加配置项, 文档地址
devServer: {
contentBase: path.resolve(__dirname, "dist"),
}
接着我们要去/dist目录新建一个index.html
最后,我们增加自动打开浏览器的配置, 从命令上获取端口
// 引入插件
const OpenBrowserPlugin = require('open-browser-webpack-plugin');
// 获取端口
let argv = require('yargs').argv;
argv.port = argv.port || 9000;
// 在webpack的配置对象中新增plugins项
plugins: [
new OpenBrowserPlugin({ url: 'http://localhost:' + argv.port })
]
OK!我们 npm start ,一切都在我们的掌控之中,很简单,我们完成了第一个需求!!
2. 我要编译React
先下载依赖 react react-dom
然后我们进到./index.js, 引入react
'use strict';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return (
Hello stupid guys
)
}
}
ReactDOM.render(
,
document.getElementById('container')
);
那么我们对应的html就要改动一下,增加对应id
Hello World
正在加载...
好,我们要开始增加webpack对应的配置项了
module:{
rules: [
]
}
不同类型模块比如 js、css、jsx、less
那么怎么处理呢?假设我要处理js和jsx, 这里也是接收一个对象
我们先看下有哪些常用的配置项
{ test: Condition }
:匹配特定条件。一般是提供一个正则表达式或正则表达式的数组,但这不是强制的。{ use: { loader: "", options: {} } }
:指定使用一个 loader, options可以理解为是loader的选项
这里要重点说一下loader,到底是个什么东西,怎么用!
我们熟知的babel-loader, 就是用来帮我们编译的,将高版本的语言翻译到同语言的低版本
不要以下载babel-loader这个依赖就可以了,它是由无数个包组成的,它的几个核心包也要一起下
我用我查阅资料后蹩脚的总结给大家大概说一下它的工作流是怎样的
当我们输入ES6语法后,babel-core里面会调用babel.transform去解析,返回{ code, map, ast },
然后再根据loader中的option配置去将前面返回的AST树翻译成配置对应的代码
babel.transform(code, options) // => { code, map, ast }
for example...
var es6Code = 'let x = n => n + 1';
var es5Code = require('babel-core')
.transform(es6Code, {
presets: ['es2015']
})
.code;
// '"use strict";\n\nvar x = function x(n) {\n return n + 1;\n};'
再比如我要编译react代码,那么我需要配置一个预设插件去翻译, babel-preset-react-app
理解上面这两个配置项,你就已经离熟悉webpack不远了,那我们就快点来进行配置吧!
module: {
rules: [
{
// 特定条件
test: /\.(js|jsx|mjs)$/,
// 指定使用 loader
use: {
loader: "babel-loader",
options: {
// 这里就是我上面说的预设插件,翻译react
// !!下载babel-preset-react-app依赖!!
presets: ["react", "env"],
}
},
}
]
}
这时候,就搞定了编译React了, 我们再 npm start ,挖槽,世界是这么的和谐!有没有很简单!?
3. 我要编译Less
我们首先会想到less-loader,我们看下它的文档 less-loader文档
根据我们上面的理解,我们再来看less-loader就很好懂了。下载依赖,根据它这么配置,就可以跑起来了,注意还有style-loader、css-loader需要下载!
但是!!我们会发现,构建出来并没有css文件呀!一看dist/index.js才发现,它把样式打进去js里面,那这样不是很友好,我们希望它有个单独的css。那么less-loader下面也有说到,通常会搭配extract-text-webpack-plugin这个插件一起使用,顾名思义,它就是抽取样式的
那么我们继续根据文档使用
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const extractLess = new ExtractTextPlugin({
filename: "[name].[contenthash].css"
});
module.exports = {
...
module: {
rules: [{
test: /\.less$/,
use: extractLess.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}]
},
plugins: [
extractLess
]
};
下载依赖!npm i extract-text-webpack-plugin@next -D
需要下载最新版本,对应webpack4,不要构建会报错
现在我们新建一个less文件,写点样式,应用到项目中,记得在index.html中引入哦!
然后再 npm start ,我去!又搞定一个!!
4. 构建项目
先看package中的build命令
"build": "./node_modules/.bin/webpack --config ./webpack.config.js --mode=production"
迫不及待要build一下了!我们先试试 npm run build
检查发现,css文件没有被压缩!
我们把下面这个配置加到css-loader、less-loader下面就可以了!
options: {
minimize: true
}
总结
静下心整个看下来,没有想象中那么复杂吧。。。可以使用它完成一个简单项目的脚手架了
但是里面还有很多很多很多需要完善的。
需要大家自己去里面探索~
谢谢