Open 1h1h opened 4 years ago
webpack是一个现代JavaScript的模块化的打包工具
4个核心概念
3件事
基本知识
webpack
前端工程化
gulp.task('watch', function(cb) { runSequence( ['copy:img', 'sass', 'include', 'copy:js'], 'dev', cb ); }); gulp.task('start', ['clean:dist', 'clean:tmp'], plugins.shell.task([ 'concurrently "gulp watch" "npm start"' ])); gulp.task('debug', ['clean:dist', 'clean:tmp'],plugins.shell.task([ 'concurrently "gulp watch" "npm run debug"' ])); gulp.task('build', function(cb) { runSequence( ['clean:dist', 'clean:tmp'], 'build:img', ['build:css', 'build:js'], 'build:html', 'clean:tmp', cb ); });
设置文件入口,单文件或者多文件
// entry 单个文件入口 const path = require('path') module.export = { entry: './src/main.js' } // 多个文件入口,采用对象形式 entry: { index: path.join(__dirname, 'src/main.js'), more: path.join(__dirname, 'src/more.js') }
output: { // 输出名字 filename: 'js/[name].[hash].js', // 采用哈希 path: path.join(__dirname, 'dist') }
module: { rules: [ { test: /\.less$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'less-loader'} ] } ] }
plugins
new
// 插件 plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, 'index.html') }), // 每次构建前清除dist文件 new CleanWebpackPlugin() ]
yarn init
yarn add webpack webpack-cli webpack-dev-server webpack-merge --dev
webpack-merge: 可用于合并公共配置和开发配置或者生产配置
webpack-merge
package.json
yarn dev || yarn build
"scripts": { "dev": "webpack-dev-server --config webpack.dev.js --mode development", "build": "webpack --config webpack.prod.js --mode production" },
其中require引用,loader引用的需要执行安装·yarn add xxx --dev
yarn add xxx --dev
用到plugins
html-webpack-plugin: 将打包完成的文件内联到生成的HTML文件中
html-webpack-plugin
clean-webpack-plugin: 每次执行是都清除dist文件
clean-webpack-plugin
安装yarn add babel-loader@7.1.1 babel-code --dev存在版本问题
yarn add babel-loader@7.1.1 babel-code --dev
const path = require('path'); const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const {CleanWebpackPlugin} = require('clean-webpack-plugin') // 对象 module.exports = { // 入口 entry: { index: path.join(__dirname, 'src/main.js'), more: path.join(__dirname, 'src/more.js') }, // 出口 output: { filename: 'js/[name].[hash].js', path: path.join(__dirname, 'dist') }, // loader module: { rules: [ { test: /\.css$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, ], }, // 配置less { test: /\.less$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'less-loader'} ] }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src')], }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]'), }, }, ] }, // 插件 plugins: [ new HtmlWebpackPlugin({ template: path.join(__dirname, 'index.html') }), // 每次构建前清除dist文件 new CleanWebpackPlugin() ] }
webpack.base.js
const merge = require("webpack-merge") const common = require('./webpack.base.js') // 引入公有模块 module.exports = merge(common, { mode: "production" })
devServer
webpack.HotModuleReplacementPlugin
const merge = require('webpack-merge') // 引入webpack-merge功能模块 const common = require('./webpack.base.js') // 引入公有模块 const webpack = require('webpack') // 由于许多不同环境,我们需要抽离公共部分 module.exports = merge(common, { devServer: { contentBase: './dist', // 本地服务器加载文件的目录 port: '8899', // 设置端口号 inline: true, // 文件修改后时时刷新 historyApiFallback: true, // 不跳转 hot: true // 热更新 }, // 热更新插件 plugins: [ new webpack.HotModuleReplacementPlugin({ multiStep: true }) ], mode: "development" })
这样,一个基本的框架就完成。但是这远远不够,还没有加入现在流行的单页面框架react,vue,接下来,就采用vue来搭建单页面
react
vue
yarn add vue vue-loader vue-template-compiler --dev
在main.js中引入vue
main.js
import Vue from 'vue'; import APP from './App.vue'; // 引入App.vue import router from './router'; new Vue({ el: '#app', router, // store, render: h => h(App) })
在index.html修改添加id = app
id = app
<div id="app"></div> // 解决找不到Cannot find element: #app
添加App.vue
App.vue
添加router.js
router.js
直接使用component:import('xx')会报错,Unexpected token,
component:import('xx')
Unexpected token
可以采用 r => require.ensure( [], () => r (require('../src/component/home.vue')))
r => require.ensure( [], () => r (require('../src/component/home.vue')))
或者 yarn add babel-plugin-syntax-dynamic-import --dev,
yarn add babel-plugin-syntax-dynamic-import --dev
修改webpack.base.js中
{ test: /\.js$/, loader: 'babel-loader', // include: [path.join(__dirname, 'src')], exclude : /node_modules/, options: { plugins: ['syntax-dynamic-import'] }, },
router.js代码如下:
import Vue from 'vue' import Router from 'vue-router'; // import Home from '../src/component/home.vue' //const Home = r => require.ensure( [], () => r (require('../src/component/home.vue'))) Vue.use(Router) const router = new Router({ mode: 'history', routes: [ { path: '/', name: 'home', component: () => import('../src/component/home.vue') } ] }) router.beforeEach((to, from, next) => { next() }) export default router;
这样就完成了基本VUE项目搭建,主要在webpack.base.js
const path = require('path'); const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const {CleanWebpackPlugin} = require('clean-webpack-plugin') const VueLoaderPlugin = require('vue-loader/lib/plugin.js') module.exports = { // 入口 entry: { index: path.join(__dirname, 'src/main.js'), // more: path.join(__dirname, 'src/more.js') }, resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js', '@': path.resolve(__dirname, '../src') }, }, // loader module: { rules: [ { test: /\.css$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, ], }, // 配置less { test: /\.less$/, use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'less-loader'} ] }, { test: /\.js$/, loader: 'babel-loader', // include: [path.join(__dirname, 'src')], exclude : /node_modules/, options: { plugins: ['syntax-dynamic-import'] }, }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'img/[name].[hash:7].[ext]', outputPath: path.join(__dirname, 'dist/') }, }, { test: /\.(eot|woff|woff2|ttf)$/, loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } }, { test: /\.vue$/, use: ['vue-loader'] } ] }, // 插件 plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin({ template: path.join(__dirname, 'index.html') }), // 每次构建前清除dist文件 new CleanWebpackPlugin(), ], // 出口 output: { filename: 'js/[name].[hash].js', path: path.join(__dirname, 'dist') }, }
安装yarn add mini-css-extract-plugin --dev
yarn add mini-css-extract-plugin --dev
将style-loader替换成MiniCssExtractPlugin.loader
style-loader
MiniCssExtractPlugin.loader
{ test: /\.(le|c)ss$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } }, 'css-loader', 'less-loader' ] }, plugins: [ // 输出 new MiniCssExtractPlugin({ filename: "css/[name].[contenthash:8].css", chunkFilename: "css/[id].[contenthash:8].css" }) ]
安装:yarn add purifycss-webpack purify-css glob --dev不太可靠
yarn add purifycss-webpack purify-css glob --dev
安装yarn add optimize-css-assets-webpack-plugin --dev
yarn add optimize-css-assets-webpack-plugin --dev
// 压缩CSS代码 const optimizeCssAssetsWebpack = require('optimize-css-assets-webpack-plugin') optimization: { minimizer: [ new optimizeCssAssetsWebpack({}) ] }
安装: yarn add terser-webpack-plugin --dev
yarn add terser-webpack-plugin --dev
const terserWebpackPlugin = require('terser-webpack-plugin') new terserWebpackPlugin({ parallel: 2, // 开启几个进程来处理压缩, cache: true })
optimization: { // 分离chunks,不必要第三方 splitChunks: { chunks: "all", minSize: 30000, maxSize: 0, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: "-", // chunk分隔符 name: true, cacheGroups: { // 设置缓存组用来抽取满足不同规则的chunk element: { name: "chunk-element-ui", priority: -9, chunks: "all", test: /[\\/]node_modules[\\/](element-ui)/, reuseExistingChunk: true, // 重复使用已经存在的块 enforce: true, // 强制生成 }, } },
安装 yarn add compression-webpack-plugin --dev
yarn add compression-webpack-plugin --dev
// 若已经经过图片或者其他压缩的,gzip压缩不明显 plugins: [ new CompressionPlugin({ // gzip压缩配置 test: /\.js$|\.html$|\.css/, // 匹配文件名 threshold: 10240, // 对超过10kb的数据进行压缩 deleteOriginalAssets: false, // 是否删除原文件 }), ],
webpack4 配置
从零搭建webpack工程化项目
1.webpack简介
webpack是一个现代JavaScript的模块化的打包工具
4个核心概念
3件事
基本知识
webpack
,前端工程化
,2. webpack 、gulp区别
1.webpack: 基于模块化打包工具
2.gulp:基于任务流的构建工具
3.核心配置
1 entry(入口)
设置文件入口,单文件或者多文件
2. output(出口)
3 loader
4 plugins(插件)
plugins
属性传入new
实例。4 搭建webpack基本框架
1.项目初始化(webpack-demo)
2.
yarn init
3.安装webpack包
yarn add webpack webpack-cli webpack-dev-server webpack-merge --dev
webpack-merge
: 可用于合并公共配置和开发配置或者生产配置4修改
package.json
,启动脚手架命令yarn dev || yarn build
5.webpack.base.js 中为配置公共部分
其中require引用,loader引用的需要执行安装·
yarn add xxx --dev
用到plugins
html-webpack-plugin
: 将打包完成的文件内联到生成的HTML文件中clean-webpack-plugin
: 每次执行是都清除dist文件安装
yarn add babel-loader@7.1.1 babel-code --dev
存在版本问题6.webpack.prod.js生产版本配置
webpack.base.js
合并过来7.webpack.dev.js开发版本配置
webpack.base.js
合并过来devServer
配置端口,加载目录,以及热更新webpack.HotModuleReplacementPlugin
这样,一个基本的框架就完成。但是这远远不够,还没有加入现在流行的单页面框架
react
,vue
,接下来,就采用vue来搭建单页面5添加vue完成搭建
1.安装vue依赖
yarn add vue vue-loader vue-template-compiler --dev
2整改原先项目
在
main.js
中引入vue
在index.html修改添加
id = app
添加
App.vue
添加
router.js
直接使用
component:import('xx')
会报错,Unexpected token
,可以采用
r => require.ensure( [], () => r (require('../src/component/home.vue')))
或者
yarn add babel-plugin-syntax-dynamic-import --dev
,修改
webpack.base.js
中router.js代码如下:
这样就完成了基本VUE项目搭建,主要在
webpack.base.js
6 打包优化
1 分离CSS文件
安装
yarn add mini-css-extract-plugin --dev
将
style-loader
替换成MiniCssExtractPlugin.loader
2 消除冗余css
安装:
yarn add purifycss-webpack purify-css glob --dev
不太可靠3 压缩CSS代码
安装
yarn add optimize-css-assets-webpack-plugin --dev
4 压缩JS代码
安装:
yarn add terser-webpack-plugin --dev
5 分离不常用的第三方插件
6 gZip 压缩
安装
yarn add compression-webpack-plugin --dev