webpack
上一篇:项目部署CentOS 7.2
介绍
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
- 理解依赖关系图
任何时候,一个文件依赖于另一个文件,webpack 就把此视为文件之间有 依赖关系 。这使得 webpack 可以接收非代码资源(non-code asset)(例如图像或 web 字体),并且可以把它们作为 依赖 提供给你的应用程序
理解四个核心概念:
-
入口(entry):指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始【每个依赖项随即被处理,最后输出到称之为 bundles 的文件中】
指定一个入口起点(或多个入口起点)。默认值为 ./src
-
输出(output):告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
整个应用程序结构,都会被编译到你指定的输出路径的文件夹中
-
loader(解析器):loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块
webpack 自身只理解 JavaScript
- loader 有两个目标
- test 属性:用于标识出应该被对应的 loader 进行转换的某个或某些文件
- use 属性:表示进行转换时,应该使用哪个 loader
- loader 有两个目标
-
插件(plugins):插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
最后还有一个模式--》通过选择 development 或 production 之中的一个
module.exports = {
mode: 'production'
};
总结详解
前言:
module.exports = {
//入口文件的配置项
entry: {},
//出口文件的配置项
output: {},
//模块:例如解读CSS,图片如何转换,压缩
module: {},
//插件,用于生产模版和各项功能
plugins: [],
//配置webpack开发服务功能
devServer: {}
}
入口entry(单入口与多入口)
-
写法
-
单入口
const config = { //字符串----------------(是下面对象的简写) entry:'./path/to/my/entry/file.js' //对象 entry: { 'main':'./path/to/my/entry/file.js' } //数组 /* * 在你想要多个依赖文件一起注入,并且将它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用 * 简单说-》 把几个文件合并到一起的时候,给entry中传入数组就行了 */ entry: ['name.js', './path/to/my/entry/file.js'], }; module.exports = config; -
多入口:entry: {[entryChunkName: string]: string|Array<string}
const config = { //对象 entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js', pageThree: './src/pageThree/index.js' } }; module.exports = config;
-
分离 应用程序(app) 和 第三方库(vendor) 入口 文档
动态入口 文档
输出(output)
-
写法
-
__dirname:node模块,表示当前目录
// 定义webpack如何输出的选项 output: { // path.resolve用来拼接文件多级目录 // __dirname 为当前文件所在全路径地址 path: path.resolve(__dirname, "dist"), // string // 「入口(entry chunk)」文件命名模版 // 多入口设置唯一,单入口可以是死的名 filename: "[chunkhash].js", // string // 按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等 publicPath: "/assets/", // string /* 其它高级配置 */ } -
filename: "[chunkhash].js"
-
publicPath: "/assets/" 文档
webpack-dev-server 也会默认从 publicPath 为基准,使用它来决定在哪个目录下启用服务,来访问 webpack 输出的文件。
-
loader(解析器)
-
Vue需要什么解析器呢?【VueLoaderPlugin插件必须引入文档】
-
vue-loader(重要点):处理 .vue 文件--》【单独一个 vue-loader 并不能解决问题:vue-template-compiler(vue-template-compiler是vue-loader必须的依赖)】
-
安装
npm install -D vue-loader vue-template-compiler -
代码
// webpack.config.js const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { module: { rules: [ // ... 其它规则 { test: /\.vue$/, loader: 'vue-loader' } ] }, plugins: [ // 请确保引入这个插件! new VueLoaderPlugin() ] }
-
-
vue-template-compiler:用于把 Vue 的模板文件(应该指.vue)预编译为渲染函数,避免运行时再编译带来的性能开销
-
为了能够编写预处理css--->node-sass以及sass-loader 【node-sass 把 sass编译成css,sass-loader把webpack的loader】
-
安装
npm install -D sass-loader node-sass -
代码
module.exports = { module: { rules: [ // ... 忽略其它规则 // 普通的 `.scss` 文件和 `*.vue` 文件中的 // `<style lang="scss">` 块都应用它 //在 vue 中,我们更推荐使用 vue-style-loader { test: /\.scss$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader' ] }, //sass-loader 会默认处理不基于缩进的 scss 语法。为了使用基于缩进的 sass 语法, //使用indentedSyntax为true { test: /\.sass$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ], }, ] }, // 插件忽略 } -
遇到无法加载的情况(vue-loader变成如下)
{ test: /\.vue$/, loader: 'vue-loader', options: { loaders: { // 由于sass-loader(奇怪)将SCSS作为其默认的解析模式,我们映射 // lang的“scss”和“sass”值属于右边的配置。 // 其他预处理器应该开箱即用,没有像这样的加载器配置。 'scss': [ //从左到右解析 'vue-style-loader', 'css-loader', 'sass-loader' ], 'sass': [ //从左到右解析 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' //排除 node_modules ] } } } -
处理css
-
安装
npm i css-loader -D -
代码
{ test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], }
-
-
需要能够解析es6更高级的语法:babel-loader ,@babel/core,@babel/preset-env
-
安装
npm i @babel/core babel-loader @babel/preset-env --save-dev
-
-
代码
//.babelrc { "presets": [ ["@babel/preset-env", { "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }] ] } ------------------------------------------------------------- { test: /\.js$/, loader: 'babel-loader', exclude: file => ( /node_modules/.test(file) && !/\.vue\.js/.test(file) ) } -
TypeScript
-
安装
npm install -D typescript ts-loader -
代码
// webpack.config.js module.exports = { resolve: { // 将 `.ts` 添加为一个可解析的扩展名。 extensions: ['.ts', '.js'] }, module: { rules: [ // ... 忽略其它规则 { test: /\.ts$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } } ] }, // ...plugin omitted }
-
-
处理图片资源 :file-loader【url-loader,他可以将html以及css中的图片打包成base64,性能优化减少https(适合小图,因此加上limit限制)】
npm i url-loader file-loader -D-
url-loader依赖file-loader,当图片超过限制时,等同于file-loader
{ test: /\.(png|jpg|gif|svg)$/, loader: 'url-loader', options: { limit: 10000, // 根据需求自行填写 name: '[name].[ext]?[hash]' } }
-
-
-
-
引入字体图标【npm i url-loader file-loader -D】
{ test: /\.(woff|woff2|eot|ttf|otf|svg)$/, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] }-
loader部分基本配置就出来了【css=css-loader/sass=node-sass与sass-loader/vue=vue-loader/js=bable-loader/file=file-loader】
module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ], }, { test: /\.scss$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader' ], }, { test: /\.sass$/, use: [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ], }, { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { 'scss': [ 'vue-style-loader', 'css-loader', 'sass-loader' ], 'sass': [ 'vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax' ] } // other vue-loader options go here } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'url-loader', options: { limit: 10000, // 根据需求自行填写 name: '[name].[ext]?[hash]' } } ] } //其他配置省略 }
-
-
React 需要啥呢?
-
js兼容==》
-
babel-loader:使用 Babel 转换 JavaScript依赖关系的 Webpack 加载器
-
@babel/core:即 babel-core,将 ES6 代码转换为 ES5
-
@babel/preset-env:即 babel-preset-env,根据您要支持的浏览器,决定使用哪些 transformations / plugins 和 polyfills,例如为旧浏览器提供现代浏览器的新特性
yarn add babel-loader @babel/core @babel/preset-env
-
-
安装react转换 babel-preset-react【**注:babel 7 使用了 @babel 命名空间来区分官方包,因此以前的官方包 babel-xxx 改成了 @babel/xxx】
-
@babel/preset-react:即 babel-preset-react,针对所有 React 插件的 Babel 预设,例如将 JSX 转换为函数
yarn add babel-preset-react --dev
-
-
代码(支持jsx后缀)
module.exports = { module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader' } } ] } }; ------------------------------------------------------ // .babelrc { "presets": ["@babel/preset-env", "@babel/preset-react"] }-
配置css==>安装 css-loader 和 style-loader 作为 dev 依赖项
npm i css-loader style-loader -D-
代码
{ test: /\.css$/, use: ['style-loader', 'css-loader'] } -
css模块化
{ test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: '[name]_[local]_[hash:base64]', sourceMap: true, minimize: true } } ] } -
编写预编译css
-
安装
npm install css-loader sass-loader style-loader -D -
代码
module.exports = { module: { rules: [ // ... 忽略其它规则 // 普通的 `.scss` 文件和 `*.vue` 文件中的 // `<style lang="scss">` 块都应用它 //在 vue 中,我们更推荐使用 vue-style-loader { test: /\.scss$/, use: [ 'style-loader', 'css-loader', 'sass-loader' ] }, //sass-loader 会默认处理不基于缩进的 scss 语法。为了使用基于缩进的 sass 语法, //使用indentedSyntax为true { test: /\.sass$/, use: [ 'style-loader', 'css-loader', 'sass-loader?indentedSyntax' ], }, ] }, // 插件忽略 } -
处理图片资源 :file-loader【url-loader,他可以将html以及css中的图片打包成base64,性能优化减少https(适合小图,因此加上limit限制)】
npm i url-loader file-loader -D-
url-loader依赖file-loader,当图片超过限制时,等同于file-loader
{ test: /\.(png|jpg|gif|svg)$/, loader: 'url-loader', options: { limit: 10000, // 根据需求自行填写 name: '[name].[ext]?[hash]' } } -
引入字体图标【npm i url-loader file-loader -D】
{ test: /\.(woff|woff2|eot|ttf|otf|svg)$/, use: [ { loader: 'url-loader', options: { limit: 8192 } } ] }
-
-
-
-
-
插件(plugins)
-
HtmlWebpackPlugin来将我们output的js和html结合起来
-
安装
npm install html-webpack-plugin --save -
代码
-
filename:可以设置html输出的路径和文件名
-
template:可以设置已哪个html文件为模版(更多的参数)
const HtmlWebpackPlugin = require('html-webpack-plugin'); ... plugins: [ new HtmlWebpackPlugin({ filename: './dist/index.html', template: './index.html', }) ]
-
-
-
mini-css-extract-plugin可提取css文件到单独的文件, 最好只在生产环境下使用,以便于热重载
-
安装
npm install -D mini-css-extract-plugin -
代码
const MiniCssExtractPlugin = require('mini-css-extract-plugin') ... new MiniCssExtractPlugin({ filename: '[name].[hash].css', chunkFilename: '[id].[hash].css' })
-
-
autoprefixer可以自动帮你添加浏览器前缀
-
安装
npm i autoprefixer postcss-loader -D -
代码
module:{ rules:[ { test:/\.scss$/, use:[‘style-loader‘,‘css-loader‘,‘sass-loader‘,‘postcss-loader‘] }, { test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"] } ] } -
在webpack.config.js文件同级目录中,新建postcss.config.js文件,并且添加如下代码
module.exports = { plugins:[ require(‘autoprefixer‘) ] }
-
-
vue骨架屏 饿了吗设计推出
-
clean-webpack-plugin:webpack 会生成文件,然后将这些文件放置在 dist文件夹中,但是 webpack 无法追踪到哪些文件是实际在项目中用到的。通常,在每次构建前清理 dist
-
安装
npm i -D clean-webpack-plugin -
代码
const CleanWebpackPlugin = require('clean-webpack-plugin') plugins: [ new CleanWebpackPlugin(["dist"]) ]
-
-
HotModuleReplacementPlugin热更新(不是局部的)【依赖于webpack-dev-server--》查看下面配置webpack-dev-server】
plugins: [ new webpack.HotModuleReplacementPlugin() ]-
(React实现局部)可以使用react-hot-loader
-
安装包
npm install --save-dev react-hot-loader -
修改.babelrc配置文件(加上)
{ plugins: ["react-hot-loader/babel"] }
-
-
了解现代框架带的局部更新
devServer
-
开服务( webpack-dev-server 的选项。)更多的配置
devServer: { contentBase: path.join(__dirname, "dist"),//对外提供的访问内容的路径 compress: true,//是否启用gzip压缩 port: 9000//提供访问的端口 }-
配置webpack-dev-server(搭配HotModuleReplacementPlugin热更新(局部))具体看这个
-
webpack.config.js【mode与hot选择webpack里设置还是package里设置】
const webpack = require('webpack'); module.exports = { + mode: 'development', devServer: { + hot: true //这个也可以在script里设置 }, + plugins: [ + new webpack.HotModuleReplacementPlugin() + ] }; -
package.json
"start": "webpack-dev-server --hot --mode development --open",
-
-
devtool(介绍】)
//介绍
-
在开发环境中我们可以使用
module.exports = { devtool: 'cheap-module-eval-source-map' } -
在正式环境中我们可以使用
module.exports = { devtool: 'cheap-module-source-map'; }
reslove(官方文档)
-
基本设置(目的:提高打包速度)
-
modules:告诉 webpack 解析模块时应该搜索的目录【添加一个目录到模块搜索目录,此目录优先于 node_modules-》文档】
-
alias:使用别名
-
extensions:项目引入文件的时候 ,数组里有的后缀,引入路径的文件后缀不需要带了【频率高的文件尽量写在前面】
resolve: { // 解析模块 modules: ['node_modules'] extensions: [".js", ".json", ".jsx", ".css"], // 用到的文件的扩展 alias: { // 模块别名列表 "module": "new-module" }, }
-
代理跨域(详细文档)
devServer: {
proxy: {
'/api': 'http://localhost:3000'
}
}
}
环境选择
-
生产环境
if (process.env.NODE_ENV === 'production') { module.exports.devtool = '#source-map' //。。。。。。 }
package.json
-
hot也可以在devServer里设置
"scripts": { "start": "webpack-dev-server --hot --mode development --open", "build": "webpack --mode production" }
现代化框架所需要的基础包依赖
-
Vue
npm i vue vue-router vuex -S -
React
-
react-router: 实现了路由的核心功能
-
react-router-dom: 基于react-router,加入了在浏览器运行环境下的一些功能,例如:Link组件,会渲染一个a标签,Link组件源码a标签行; BrowserRouter和HashRouter组件,前者使用pushState和popState事件构建路由,后者使用window.location.hash和hashchange事件构建路由
npm i react react-dom redux react-redux react-router react-router-dom -S
-