内容简介:作为一个复制粘贴工程师,一直以来都是(可能只有我这样 o(╥﹏╥)o )类似这样的脚手架命令一顿操作,什么Babel啊、Postcss、各种Loader、Eslint啊Uglifyjs都一把梭好了,然鹅到底这些是怎么配置的,不满足需求的时候怎么办呢? 这些脚手架都是基于Webpack(Webpack是什么?点我)的,最近在写原生JS项目,没有了脚手架就没有Babel、autoprefixer、Uglifyjs了,那谁给我转代码,谁给我加浏览器前缀、谁给我压缩代码啊!复制粘贴工程师的自我修养告诉我不能这样,这
作为一个复制粘贴工程师,一直以来都是(可能只有我这样 o(╥﹏╥)o )
vue create hello-world npx create-react-app hello-world 复制代码
类似这样的脚手架命令一顿操作,什么Babel啊、Postcss、各种Loader、Eslint啊Uglifyjs都一把梭好了,然鹅到底这些是怎么配置的,不满足需求的时候怎么办呢? 这些脚手架都是基于Webpack(Webpack是什么?点我)的,最近在写原生JS项目,没有了脚手架就没有Babel、autoprefixer、Uglifyjs了,那谁给我转代码,谁给我加浏览器前缀、谁给我压缩代码啊!复制粘贴工程师的自我修养告诉我不能这样,这些活还是别人干ヽ(✿゚▽゚)ノ
于是就开始了新的复制之旅
开始
先来复制一段,新建个项目,项目根目录下 npm init -y
, -y 就是全yes了,至于yes了啥胸弟们可以不-y试试 ︿( ̄︶ ̄)︿
项目目录下多了个package.json,里面记录了项目相关的信息。
基于Webpack我们当然要安装Webpack了
npm i webpack webpack-cli -D 复制代码
命令完成后,项目中多了一个 node_modules文件夹,该文件夹是用来存放项目中安装的依赖包,以后项目依赖的包也都会在里面。
初始化项目目录,新建src、dist、config以及index.html(html里随便写点啥比如hello world等会打开了至少不是白的就行),还有src目录下的入口文件index.js(空的即可)
初始化工作基本就完成了 webpack打包默认入口为src/index.js, 默认打包模式为 --mode development, 打包模式总共有两种:
- mode development(开发环境)
- mode production(生产环境)
现在可以在package.json -> scripts 栏目 配置build的命令
{ "name": "test-webpack-bundler", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --mode production" }, 下面太长省略了... } 复制代码
然后执行 npm run build
看已经打包成功了! 长征才刚刚开始...
webpack配置工程师警告(๑•̀ㅂ•́)و✧
webpack配置之旅
先 npm i webpack-dev-server html-webpack-plugin internal-ip -D
开发环境本地服务就靠 webpack-dev-server 了,生成html、自动插入js等就靠 html-webpack-plugin 了,局域网设备可通过IP访问就靠 internal-ip 在config目录里新建一个 webpack.dev.js
又到了复制粘贴的时候啦
const path = require("path"); const webpack = require("webpack"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const packageConfig = require("../package.json"); const internalIp = require('internal-ip') // 借助这个实现可用局域网IP访问 const devWebpackConfig = { mode: "development", devtool:'#source-map', devServer: { port: 9527, // 指定端口号; 默认 8080 hot: true, // 热更新 host: internalIp.v4.sync(), // 可通过局域网IP访问,也可以通过 localhost 访问 open: true, // 启动本地服务后,自动打开页面 overlay: true, // 编译器错误或警告时, 在浏览器中显示全屏覆盖; 默认false progress: true, // 是否将运行进度输出到控制台; 默认 false contentBase: path.resolve(__dirname, "dist"), // 告诉服务器从哪里提供内容。只有在你想要提供静态文件时才需要 publicPath: "/", // 精简终端输出 stats: { modules: false, children: false, chunks: false, chunkModules: false } }, entry: ["./src/index.js"], plugins: [ new HtmlWebpackPlugin({ template: "index.html", // 指定模板html文件 title: packageConfig.name, // html的title的值,这里我从package.json里取了 inject: true, // 自动引入JS脚本的位置,默认值为 true }) ] }; module.exports = devWebpackConfig; 复制代码
devtool详情看这里 现在在package.json -> scripts 中配置dev的命令
"dev": "webpack-dev-server --config config/webpack.dev.js --color --progress" 复制代码
现在 npm run dev
吧 胸弟们熟悉的不要不要的了吧,走你
没问题我们继续,有问题···胸弟们百度一下吧
现在我们就参考Vue Cli生成的项目整理目录吧
- assets 主要是图片啊 图标啊 字体啊 之类的
- styles 就是css啦
- utils 就是 工具 函数了 比如写(复制)了个防抖啊、节流啊、时间格式化啊之类的扔进去,用的时候导入即可
webpack只认识js,图标、字体、css等其他的就需要各种loader拿给webpack,它才认识。
先搞定css吧,顺便把sass和scss也搞了(less同理,找对应loader即可) 随便写几句意思一下
index.html
<header class="flex-container header-wrapper"> <h1 class="title">test-webpack4-bundler</h1> <div class="user-avatar-box"> <img class="adaptive-img" src="./src/assets/uncle.jpg" alt="" /> </div> <ul> <li class="list-item">1</li> <li class="list-item">2</li> <li class="list-item">3</li> <li class="list-item">4</li> <li class="list-item">5</li> <li class="list-item">6</li> </ul> </header> 复制代码
src/index.js
import './styles/index.scss' // global css 复制代码
src/styles/index.scss
@import "./header.scss"; .flex-container { display: flex; justify-content: center; align-items: center; } .adaptive-img { width: 100%; height: 100%; object-fit: cover; object-position: center; } 复制代码
src/styles/header.scss
.header-wrapper { flex-direction: column; .title { color: rgb(65, 85, 28); } .user-avatar-box { width: 120px; height: 120px; overflow: hidden; border-radius: 50%; } } 复制代码
复制粘贴
npm i css-loader style-loader sass-loader sass postcss-loader autoprefixer -D 复制代码
装一堆 看名字也知道大概是干什么的了吧 postcss-loader配合autoprefixer 就可以自动加-webkit这些前缀了
(当然PostCSS还能干很多事,想要了解的话点我)
config/webpack.dev.js里,和plugins同级配置loader
module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", "postcss-loader", { loader: "sass-loader", options: { implementation: require("sass") // 默认使用的node-sass,这样配置就会使用dart-sass } } // webpack的规定,多个loader要倒着写,比如scss文件先给sass-loader解析成css再给css-loader,以此类推 ] } ] } 复制代码
项目根目录下创建两个文件用来配置postcss-loader和autoprefixer
.browserslistrc
> 1% last 2 versions not ie <= 9 复制代码
postcss.config.js
module.exports = { plugins: { autoprefixer: {} } }; 复制代码
又可以 npm run dev
了 已经看到我们想要的样子并且已经自动加了针对不同内核的前缀
css部分已经结束了,现在我们写点牛逼的代码吧
utils/index.js
export function $(selector) { return document.querySelector(selector); } 复制代码
src/index.js
import "./styles/index.scss"; // global css import { $ } from "./utils"; import { resolve } from "path"; window.onload = () => { const showText = "守护姨父的微笑"; setTimeout(() => { }, 1000); const changeTitle = () => { let myPromise = new Promise((resolve, reject) => { resolve(); }); return myPromise; }; changeTitle().then(()=>{ $(".title").innerHTML = `我们要${showText}`; const lists = [...document.querySelectorAll(".list-item")]; lists.forEach(element => { console.log(element); }); let [a, b, c] = ["索尼好!退果报平安", 2, 3]; console.log(a); $(".title").innerHTML = `我们要${showText}${a}`; }) }; 复制代码
好了我们写了箭头函数、模板字符串、const声明、Promise都是es6的语法,某些不现代的浏览器不支持,所以我们需要Babel老弟帮帮我们
复制粘贴
npm i babel-loader @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import -D 复制代码
src/index.js 头部引入垫片
import "@babel/polyfill"; 复制代码
项目根目录下新建.babelrc
{ "presets": ["@babel/preset-env"], "plugins": [ "@babel/plugin-transform-runtime" ] } 复制代码
config/webpack.dev.js 里 module>rules 下增加一个loader
{ test: /\.js$/, use: ["babel-loader"], exclude: /node_modules/ }, 复制代码
config/webpack.dev.js entry加入 @babel/polyfill
entry: ["@babel/polyfill","./src/index.js"] 复制代码
package.json -> scripts build
"build": "webpack --config config/webpack.dev.js --mode production --color --progress" 复制代码
npm run build
走一波
es6的语法都没有了,该有的垫片也有了
(babel-polyfill和babel-runtime的关系和区别大概可以看这里)
好像大概是弄完了?等等,打包出来的html文件图片引用路径好像不对,没hash值迭代了缓存不得搞死我们啊,那么下一轮复制粘贴又要开始了。
开发环境大概就这么样了吧,针对生产环境我们需要再搞点东西了 先复制一份webpack.dev.js,叫webpack.prod.js,作为生产环境的webpack配置
装,分别是解决js和html里的文件路径问题
npm i url-loader file-loader html-withimg-loader -D 复制代码
然后删除开发服务器,
config/webpack.prod.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const packageConfig = require("../package.json"); const prodWebpackConfig = { mode: "production", devtool: false, entry: ["@babel/polyfill", "./src/index.js"], output: { path: path.resolve(__dirname, "../dist"), filename: path.posix.join("static", "js/[name].[chunkhash].js"), chunkFilename: path.posix.join("static", "js/[id].[chunkhash].js") }, module: { rules: [ { test: /\.js$/, use: ["babel-loader"], exclude: /node_modules/ }, { test: /\.(sa|sc|c)ss$/, use: [ "style-loader", "css-loader", "postcss-loader", { loader: "sass-loader", options: { implementation: require("sass") // 默认使用的node-sass,这样配置就会使用dart-sass } } // webpack的规定,多个loader要倒着写,比如scss文件先给sass-loader解析成css再给css-loader,以此类推 ] }, { test: /\.(htm|html)$/, loader: "html-withimg-loader" }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: "url-loader", options: { limit: 10000, name: path.posix.join("static", "img/[name].[hash:7].[ext]") } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: "url-loader", options: { limit: 10000, name: path.posix.join("static", "fonts/[name].[hash:7].[ext]") } } ] }, plugins: [ new HtmlWebpackPlugin({ template: "index.html", // 指定模板html文件 title: packageConfig.name, // html的title的值,这里我从package.json里取了 inject: true, // 自动引入JS脚本的位置,默认值为 true minify: { minifycss: true, // 压缩css minifyJS: true, // 压缩JS removeComments: true, // 去掉注释 collapseWhitespace: true, // 去掉空行 removeRedundantAttributes: true, // 去掉多余的属性 removeAttributeQuotes:true, // 删除不需要引号的属性值 removeEmptyAttributes: true // 去掉空属性 } }) ] }; module.exports = prodWebpackConfig; 复制代码
package.json -> scripts build 该用生产环境的配置build了
"build": "webpack --config config/webpack.prod.js --mode production --color --progress" 复制代码
npm run build
走一波
可以看到,html压缩过了,img路径也正确了,同时目录结构也整齐多了,文件也带了hash值
大体上完成了,后续还有一些优化,比如用指定的插件去压缩JS,CSS抽离成单个文件并优化,将根目录下的static下静态资源copy到打包目录下等,单独抽离第三方库等,就不一一说了,主要写这玩意太累了。。。大佬们好牛逼。。。。真的
如果有哪里有问题欢迎大佬们告诉我 感恩!
附上这个项目的地址里面包含了完整的配置
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 从0开始构建SpringCloud微服务(1)
- 从零开始构建企业级推荐系统
- 图解 BERT 模型:从零开始构建 BERT
- 从理解 Phoenix 索引源码开始,构建全文索引
- 使用gRPC从零开始构建Go微服务
- 从零开始构建Flink开发项目-Scala版
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The CS Detective: An Algorithmic Tale of Crime, Conspiracy, and
Jeremy Kubica / No Starch Press / 2016-8-15 / USD 13.74
Meet Frank Runtime. Disgraced ex-detective. Hard-boiled private eye. Search expert.When a robbery hits police headquarters, it's up to Frank Runtime and his extensive search skills to catch the culpri......一起来看看 《The CS Detective: An Algorithmic Tale of Crime, Conspiracy, and 》 这本书的介绍吧!