第12天课程-多页:多入口,匹配多个打包的jscss
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'development', entry: { home: './src/home.js', other: './src/other.js' }, output: { filename: '[name].js', path: path.resolve(__dirname, 'dist') }, plugins: [ new HtmlWebpackPlugin({ template: './src/home.html', filename: 'home.html', chunks:['home'] }), new HtmlWebpackPlugin({ template: './src/other.html', filename: 'other.html', chunks:['other'] }) ] }
补充章节:webpack-modehtml
mode分为development/production,默认为production。每一个选项的默认配置以下(common指两个配置项都存在的属性):前端
common:vue
//parent chunk中解决了的chunk会被删除 optimization.removeAvailableModules:true //删除空的chunks optimization.removeEmptyChunks:true //合并重复的chunk optimization.mergeDuplicateChunks:true
production node
//性能相关配置 performance:{hints:"error"....} //某些chunk的子chunk已一种方式被肯定和标记,这些子chunks在加载更大的块时没必要加载 optimization.flagIncludedChunks:true //给常常使用的ids更短的值 optimization.occurrenceOrder:true //肯定每一个模块下被使用的导出 optimization.usedExports:true //识别package.json or rules sideEffects 标志 optimization.sideEffects:true //尝试查找模块图中能够安全链接到单个模块中的段。- - optimization.concatenateModules:true //使用uglify-js压缩代码 optimization.minimize:true
developmentreact
//调试 devtool:eval //缓存模块, 避免在未更改时重建它们。 cache:true //缓存已解决的依赖项, 避免从新解析它们。 module.unsafeCache:true //在 bundle 中引入「所包含模块信息」的相关注释 output.pathinfo:true //在可能的状况下肯定每一个模块的导出,被用于其余优化或代码生成。 optimization.providedExports:true //找到chunk中共享的模块,取出来生成单独的chunk optimization.splitChunks:true //为 webpack 运行时代码建立单独的chunk optimization.runtimeChunk:true //编译错误时不写入到输出 optimization.noEmitOnErrors:true //给模块有意义的名称代替ids optimization.namedModules:true //给模chunk有意义的名称代替ids optimization.namedChunks:true
webpack运行时还会根据mode设置一个全局变量process.env.NODE_ENV,jquery
这里的process.env.NODE_ENV不是node中的环境变量,而是webpack.DefinePlugin中定义的全局变量,容许你根据不一样的环境执行不一样的代码.webpack
生产环境下,uglify打包代码时会自动删除不可达代码,也就是说生产环境压缩后最终的代码为:es6
第13天课程-配置source-mapweb
安装依赖
npm install -D babel-loader @babel/core @babel/preset-env
npm install webpack-dev-server --save-dev
devtool设置项理解,eval 能够理解为发射,不是编译阶段产生
//devtool: 'source-map',//产生文件,能够显示行和列 //devtool: 'eval-source-map',//不实际产生文件,可是能够显示行和列 //devtool: 'cheap-module-source-map',//不显示列,产生文件 devtool: 'cheap-module-eval-source-map',//不显示列,不产生文件
试验代码src/home.js:
class Demo{ constructor(){ console.loga(); } } let d=new Demo();
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'production', entry: { home: './src/home.js', }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') }, //devtool: 'source-map',//产生文件,能够显示行和列 //devtool: 'eval-source-map',//不实际产生文件,可是能够显示行和列 //devtool: 'cheap-module-source-map',//不显示列,产生文件 devtool: 'cheap-module-eval-source-map',//不显示列,不产生文件 module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/home.html', filename: 'index.html', chunks: ['home'] }) ] }
14章节:watch用法,执行npm run build时候开始
更改完代码以后,当即build,产生编译文件,
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { mode: 'production', entry: { home: './src/home.js', }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') }, watch:true, watchOptions:{ poll:1000,//每秒检查一次变更 aggregateTimeout:500,//防抖延迟,500秒以后输入, ignored: /node_modules/ //ignored: "files/**/*.js" }, module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/home.html', filename: 'index.html', chunks: ['home'] }) ] }
15:webpack小插件介绍
cleanWebpackPlugin:npm install clean-webpack-plugin -D
关键代码:
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件 new CleanWebpackPlugin()
官方说明:详细说明
/** * All files inside webpack's output.path directory will be removed once, but the * directory itself will not be. If using webpack 4+'s default configuration, * everything under <PROJECT_DIR>/dist/ will be removed. * Use cleanOnceBeforeBuildPatterns to override this behavior. * * During rebuilds, all webpack assets that are not used anymore * will be removed automatically. * * See `Options and Defaults` for information */
全部output.path目录都会被一次删除,目录自己不会删除
copyWebPackPlugin:
const CopyWebpackPlugin = require('copy-webpack-plugin'); // 文件拷贝 new CopyWebpackPlugin([{from:'./doc',to:'./'}])
bannerPlugin:
let webpack=require('webpack'); new webpack.BannerPlugin('版权全部,违反必究 2019 copyright')
本章节webpack配置文件
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件 const CopyWebpackPlugin = require('copy-webpack-plugin'); // 引入清除文件插件 let webpack=require('webpack'); module.exports = { mode: 'development', entry: { home: './src/home.js', }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/home.html', filename: 'index.html', chunks: ['home'] }), new CleanWebpackPlugin(), new CopyWebpackPlugin([{from:'./doc',to:'./'}]), new webpack.BannerPlugin('版权全部,违反必究 2019 copyright') ] }
16章节:webpack跨域问题
webpack端口默认是8080 若是请求这么写,会跨域,跨域是浏览器自己的限制,若是使用浏览器跨域设置,能够请求到数据
1:devServer-proxy设置
本地express服务器:localhost:3000/api/user 代理设置:proxy:{'/api':'http://localhost:3000'}
可是不是服务端每一个接口都是api开头的,因此须要用下面的方式 本地express服务器:localhost:3000/user 代理devServer设置
2:单纯模拟数据mock 启动钩子函数
3:有服务端,可是不想用代理处理,用express 启动webpack 端口用express端口
npm install webpack-dev-middleware --save-dev //安装依赖
server.js let express = require('express'); let config=require('./webpack.config'); const webpack = require('webpack'); const middleware = require('webpack-dev-middleware'); const compiler = webpack(config); let app = express(); app.use( middleware(compiler, { }) ); app.get('/api/user', (req, res) => { res.json({ "name": "珠峰设计-express" }); }) app.listen(3000);
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 引入清除文件插件 const CopyWebpackPlugin = require('copy-webpack-plugin'); // 引入清除文件插件 let webpack = require('webpack'); module.exports = { mode: 'development', entry: { home: './src/home.js', }, devServer: { contentBase: path.join(__dirname, 'dist'), compress: true, before(app) { console.log(app); app.get('/before', (req, res) => { res.json({ "name": "我试mock数据-before" }); }) }, port: 9000, /*proxy:{ '/api':'http://localhost:3000' } */ proxy: { '/api': { target: 'http://localhost:3000', pathRewrite: { '/api': '' }//须要先启动3000端口的服务 } } }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/home.html', filename: 'index.html', chunks: ['home'] }), new CleanWebpackPlugin(), new CopyWebpackPlugin([{ from: './doc', to: './' }]), new webpack.BannerPlugin('版权全部,违反必究 2019 copyright') ] }
17:resolve属性的配置,解析的意思,文件查找别名后缀等配置
Webpack 在启动后会从配置的入口模块出发找出全部依赖的模块,Resolve 配置 Webpack 如何寻找模块所对应的文件。 Webpack 内置 JavaScript 模块化语法解析功能,默认会采用模块化标准里约定好的规则去寻找,但你也能够根据本身的须要修改默认的规则
安装后模块:就是会在node_modules里面Bin里面有,不须要"/"
模块目录指定:
别名:引入bootstrap样式为例
alias:名称比较长,可是文件名称比较长,想取一个短的名字
mainFields 可是能不能先找style 再找js mainFields:['style','main'] 字段名称为bootstrap里面package.json key
须要css的话,把css加进去
18:定义环境变量
把环境变量注入代码里面,插件:new webpack.
new webpack.DefinePlugin({ 'DEV':"'dev'", 'DevTest':JSON.stringify('devTest'), 'DevBoolean':true, 'DevBooleanWithSingle':'true', 'EXPRESSIONWITHNOTDOT':'1+1', 'EXPRESSIONWITHDOT':JSON.stringify('1+1'), }),
输出结果:
19;区分不一样环境变量
webpack.config.js分开生产和开发环境,
webpack.base.js :公共的
webpack.dev.js 开发的
webpack.prod.js 生产的
安装插件npm install webpack-merge -D
webpack.dev.js文件内容 ,这样咱们就能够把配置给分开
const { smart } = require('webpack-merge'); const base = require('./webpack.base.js'); module.exports = smart(base, {'mode':'development'})
20:优化设置
新建一个空的工程并安装插件
npm init -y npm install webpack webpack-cli html-web pack-plugin @babel/core babel-loader @babel/preset-env @babel/preset-react jquery -D
>webpack配置里面的noParse:不解析依赖项
src-index.js文件
import jquery from 'jquery';
这样反复编译几回发现,编译时间是缩短了,我电脑表现大概节约200ms时间
>IgnorePlugin插件:忽略某些模块,不打包进来
webpack配置里面exclude include排除目录(node_modules),包含src
安装moment 时间处理库:npm insall moment -D
安装开发服务器:npm install webpack-dev-server
webpack.config.js文件
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack=require('webpack'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, include:path.resolve("src"), use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', }), new webpack.IgnorePlugin(/\.\/locale/,/moment/) ], };
index.js
import jquery from 'jquery'; import moment from 'moment'; import 'moment/locale/zh-cn'; moment.locale('zh-cn');//这一句不引入也正确 let r=moment().endOf('day').fromNow(); console.log(r);
>dllPlugin插件:减小打包体积
安装npm install react react-dom
>happypack多线程打包js,css打包 中间插入一层happypack
>webpack自带的一些优化,避免没必要要的tree-shaking,做用域提高scope hosting
生产环境去除没有用的代码,开发环境有的,tree-shaking
只有import 管用,require不能够,es6模块会把结果放到default对象上
前端推荐import
webpack会省略一些能够简化的代码
25:webpack抽取公共代码 optimization-splitChunks-cacheGroups里面配置,多入口文件
webpack配置文件 optimization:{ splitChunks:{ cacheGroups:{ common:{ chunks:'initial',//抽离阶段 minSize:0,抽离大小 minChunks:2//引用多少次就开始抽离 }, vendor:{ priority:1, //避免直接走第一步,不走第二步 test:/node_modules/, chunks:'initial', minSize:0, minChunks;2 } } } }
26:懒加载功能webpack
意义:安装插件@babel/plugin-syntax-dynamic-import
vue react的路由懒加载实现
button的点击事件里面代码
import('./source.js');
options:{ presets:['@babel/preset-env','@babel/preset-react'], plugins:['@babel/plugin-syntax-dynamic-import '] }
27:webpack热更新 开发环境用 默认强制更新,从新编译
devserver:hot:true
两个插件:webpack.NamedModulesPlugin /webpack.HotModuleReplacementPlugin
index.js
import s from './a.js'; if (module.hot) { module.hot.accept('./a.js', (s) => { let a=import('./a');// a.then(function(response){ console.log(response); }); let b=require('./a.js'); console.log(b); }) }
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack=require('webpack'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, devServer:{ port:3000, open:true, hot:true, contentBase:'./dist' }, module: { rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, include:path.resolve("src"), use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react'] } } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', }), new webpack.IgnorePlugin(/\.\/locale/,/moment/), new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin() ], };
28-33:webpack-tapable 同步钩子和异步钩子
webpack 本质事件流,主要依赖于发布订阅模式