webpack
###开发依赖devDependencies与运行依赖dependencies
npm自己的文档说dependencies是运行时依赖,devDependencies是开发时的依赖。即devDependencies 下列出的模块,是我们开发时用的,比如 我们安装 js的压缩包gulp-uglify 时,我们采用的是 “npm install -D gulp-uglify ”命令安装,因为我们在发布后用不到它,而只是在我们开发才用到它。
dependencies 下的模块,则是我们发布后还需要依赖的模块,譬如像jQuery库或者Angular框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。
cnpm install express -S(–save) 运行时依赖 (express jquery )
cnpm install node-sass -D(–save-dev) 开发依赖 (gulp-uglify node-sass sass-loader babel)
webpack (facebook)
前端工程化: npm、cnpm、yarn、bower | grunt 、 gulp 、webpack (vue => cnpm run build css/html/js)
gulp: 基于流的前端自动化构建工具,基于流的任务式的工具 .pipe()**
webpack: 是一款模块化打包工具,webpack是基于配置的,通过配置一些选项来让webpack执行打包任务。
(all is js 一切皆模块)
cnpm i webpack -g
cnpm i webpack-cli -g
webpack能干啥?
打包:将多个js文件打包成一个文件 (1.减少Http请求 2.压缩页面的空格从而减轻服务器压力)
转换:把扩展的语法转换成普通js , 目的就是让浏览器正常解析运行代码(es6解析)
优化:复杂的开发流程 、进行模块化打包、去空格、压缩混淆、减少http请求等
面试题: gulp or webpack理解?
https://www.cnblogs.com/RuMengkai/p/6667321.html
相同点:都是前端自动化的构建工具
不同点:
gulp强调工作流程(对于模块化并没有进行强调)
webpack是前端模块化开发的解决方案 强调模块化、压缩合并、预处理等只不过是它的附带功能
gulp强调工作流程,通过task方法设置一个个的任务(例如文件压缩、合并、启动server等)
但是它没法解决的是 js module 的问题,是你写代码时候如何组织代码结构的问题.
webpack是一个前端模块化方案,侧重模块打包,我们可以把开发中所有的资源(图片、js文件、css资源)通过loader(加载器)和plugins(插件)对资源进行打包处理,让其生成符合生产环境部署的前端资源。
entry
webpack在打包的时候,依赖关系图,在打包的时候需要告知webpack两个概念:入口和出口
一般情况下,我们需要使用webpack.config.js进行配置
entry配置项目打包的入口,值可以为单个的字符串执行某一个文件的地址,这个时候该文件就是入口文件,webpack会根据入口文件里各模块间的关系形成依赖关系图,然后根据依赖关系图进行打包
entry:'./src/app.js',
output:{
path:path.join(__dirname,'build'),
filename:'app.js'
}
但是有的时候我们需要的是多入口,我们就写成数组的形式,数组里的每一个字符串地址指向的都是一个独立的入口,webpack会将这些入口的依赖打包
entry:['./src/app.js','./src/vendor.js'],
output:{
path:path.join(__dirname,'build'),
filename:'[name].js'//不确定名字的时候,这里会打包成main.js
}
刚才的两种entry配置都只会打包出一个js文件,但是在某一个应用中我们可能需要将js根据依赖关系打包成多个js文件,并且在多页面应用中,我们也确实不可能只使用一个js文件,那么我们就可以使用如下的配置:
entry:{
app:'./src/app.js',
vendor:'./src/vendor.js'
},
output:{
path:path.join(__dirname,'build'),
filename:'[name]_[hash].js'
}
这样,因为filename里写成名字是[name],所以会根据entry的配置的键名来为打包出的js文件命名,hash是每次打包的一个随机的hash值,可以用来做版本控制
output
在这里我们配置打包输出的一些选项
filename可以确定打包出来的文件的名字,在里面我们可以使用[name],[hash]这样的占位符
path配置打包出去的文件的路径,需要是绝对路径
注意:
打包的时候出现黄色警告,原因是因为需要webpack指明mode模式。
package.json文件:
"scripts": {
"build":"webpack --mode production --config scripts/webpack.config.js"
},
mode : production or development
后续把webpack的配置文件放入 /scripts/webpack.config.js,后续打包会报错。所以需要指明咱们的–config
output:{
//__dirname是指被执行js文件所在的文件夹目录
// path: path.resolve(__dirname, '../dist'),
//process.cwd()是指当前node命 令执行时所在的文件夹目录
path:path.resolve(process.cwd(),"dist"),
filename: '[name].[chunkhash:8].js'
}
plugins
在webpack编译用的是loader,但是有一些loader无法完成的任务,交由插件(plugin)来完成,插件的时候需要在配置项中配置plugins选项,值是数组,可以放入多个插件的使用,而一般的插件都是一个构造器,我们只需在plugins数组中放入该插件的实例即可
html-webpack-plugin (模板整合)
yarn add --dev html-webpack-plugin
这个插件可以选择是否依据模板来生成一个打包好的html文件,在里面可以配置、title、template、filename、minify等选项,详情请查阅文档
new HtmlWebpackPlugin({
template: "public/index.html",
title: "react-app",
filename: "index.html"
}),
css抽离打包(mini-css-extract-plugin )
new MiniCssExtractPlugin({
filename: 'css/[name].[chunkhash:8].css'
})
压缩css (optimize-css-assets-webpack-plugin)
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
new OptimizeCssAssetsPlugin()
拷贝静态资源 (copy-webpack-plugin)
//拷贝静态资源
new CopyPlugin({
patterns:[
{
from: path.resolve(process.cwd(), "src/static/"),
to: path.resolve(process.cwd(), "dist/static/")
}
]
}
)
LOADERS
在webpack中专门有一些东西用来编译文件、处理文件,这些东西就叫loader,loader的使用就是在配置项中,设置module,在module中设置rules值为数组,在数组里放入多个匹配规则:
test为此次匹配要匹配的文件正则规则,use代表要使用的loader
处理css
style-loader/css-loader
注意。webpack中loader的使用是从后往前的
css-loader可以将引入到js中的css代码给抽离出来,style-loader可以将抽离出来的css代码放入到style标签中
module:{
rules:[
{test:/\.css$/,use:['style-loader','css-loader']}
],
}
处理scss
node-sass/sass-loader
module:{
rules:[
{test:/\.css$/,use:['style-loader','css-loader','sass-loader']}
],
}
yarn add postcss-loader autoprefixer@9.7.6
注意:autoprefixer目前最新版本10.0.0有问题!不要安装最新的
根目录创建postcss.config.js
module.exports = {
plugins:[
require("autoprefixer")
]
}
loader配置
{
test:/\.css$/i,
use:[
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader"
]
},
{
test:/\.scss$/i,
use:[
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader"
]
}
package.json上面添加
"browserslist": [
"cover 99.5%"
]
因为ExtractTextWebpackPlugin对webpack4支持的不是很好,所以我们这样解决:
cnpm i extract-text-webpack-plugin@next -D
yarn add extract-text-webpack-plugin@next -D
@next下载的就是最新的版本,可能是开发版本 3.x的版本过时了
“extract-text-webpack-plugin”: “^4.0.0-beta.0”
另外一种方案解决:
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
new MiniCssExtractPlugin({
filename:"css/[name]_[chunkHash:8].css"
})
{
test:/\.css$/i,
use:[
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader"
]
},
{
test:/\.scss$/i,
use:[
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"sass-loader"
]
}
处理图片
file-loader
{
loader: 'file-loader',
options: {
publicPath:"/", //outputPath: 'images',
name: 'images/[name].[ext]',//publicPath + outputPath + name
},
}
url-loader
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1064,
publicPath:"/",
name: 'images/[name].[ext]',
},
},
],
},
处理es6
需要的依赖:yarn add babel@6.23.0 babel-core@6.24.1 babel-loader@7.0.0 babel-preset-es2015@6.24.1 babel-preset-react@6.24.1 -D
yarn add react react-dom -S
“babel”: “^6.23.0”,
“babel-core”: “^6.24.1”,
“babel-loader”: “^7.0.0”,
“babel-preset-es2015”: “^6.24.1”,
“babel-preset-react”: “^6.24.1”,
{
test:/\.js$/,
exclude: /node_modules/,
loader:'babel-loader',
query: {
presets: ['es2015','react','stage-0' ]
}
}
然后安装babel-preset-stage-0(es7草案语法):
yarn add babel-preset-stage-0
https://www.cnblogs.com/75115926/p/12627009.html
说一下babel-loader将es6转成es5的代码实现原理!
ES6中的react
1.创建组件
使用class来创建组件
class App extends React.Component {
}
2.默认状态的设置
在es6中不再使用getInitialState来设置默认状态,而是在constructor里面直接给this.state上挂载状态
class App extends Component {
constructor(props){
super(props)
}
}
3. 默认属性的设置
在es6中,通过给类设置defaultProps属性来设置默认属性
App.defaultProps = {
name:'App根组件'
}
4.做属性传参验证
import PropTypes from 'prop-types';
App.propTypes = {
name:PropTypes.string
}
5.钩子函数有变化
getDefaultProps、getInitialState没有了
多出了constructor,而这个函数本身是类的构造器,在这里相当于getDefaultProps、getInitialState的结合
create-react-app 脚手架
cnpm install create-react-app -g
create-react-app my-app //生成一个react开发模板在my-app目录
生成的过程特别缓慢,可以使用yarn工具来下载,也就是说先去下载安装yarn :npm install yarn -g
当我们要进行二次配置的时候,需要找到node_modules文件夹里的react-scripts进行配置,但是当我们执行npm run eject就可以将配置文件抽出,方便开发配置