JS进阶 -- 工程化之 webpack
代码链接
概述
工程化包括了自动化 + 模块化 + 性能优化,前端语言较多并且更新频率较快。1
2
3CSS ==> Less ==> Sass ==> Scss ==> Stylus(结合Less + Sass)
JS ==> coffee ==> ES6 ==> babel ==> TypeScript ==> Elm
HTML ==> Jade ==> Pug ==> slim
当我们面对这么多语言的时候,Webpack 应运而生,Webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler),它主要为我们解决了工程化的问题。在本篇文章中将要介绍 SCSS + babel + Webpack
Sass | Scss
Scss 是 CSS 的预处理语言 | 扩展,Sass makes CSS fun again
这是Scss 要做的事情。Scss添加了嵌套规则、变量、混入、选择器继承,还能和命令行工具 | Web框架插件将其转换为格式良好的标准 CSS
Sass 与 Scss 区别
Sass 使用换行 + 缩进进行工作1
2body
background: red
Scss 使用分号 + 花括号进行工作1
2
3body{
background: red;
}
安装 Scss
Scss 是有 Ruby 社区创作出来的,所以要使用 gem
命令,但是 node
将 Scss 重写了一遍,所以可以使用 node-sass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37npm install -g node-sass // 安装
npm uninstall node-sass -g // 卸载
解决问题 4 连
npm update
npm install
nodejs node_modules/node-sass/scripts/install.js
npm rebuild node-sass
解决问题 7 连 查看 node-sass 是否存在
npm -v
node -v
node -p process.versions
node -p process.platform
node -p process.arch
node -p "require('node-sass').info"
npm ls node-sass
解决问题 3 连 重新生成 node_modules + package.json
npm -rf node_modules
rm package.json
rm package-lock.json
npm install
npm cache clean // 清除缓存
npm cache clean --force // 清除缓存
npm install --unsafe-perm
npm config set sass_binary_site http://npm.taobao.org/mirrors/node-sass/ // 切换淘宝源
npm i -g node-sass --save_binary_path=/home/wubowen/Downloads/Linux-x64-48-binding.node // 通过 .node 包安装
npm install -g cnpm --registry=https://registry.npm.taobao.org // 安装 cnpm
cnpm install -g node-sass // cnpm 安装
运行配置文件
. ~/.bash_profile
. ~/.npmrc
source ~/.profile
source .npmrc
安装成功之后便可以使用 node-sass 了1
2
3
4node-sass [options] <input> [output]
示例
node-sass src/style.scss dist/style.css
node-sass src/style.scss dist/style.css -w // Watch a directory or file
babel
Babel is a JavaScript compiler。它是一款可以将 JS 语法编译为 ES5(IE能读)的编译器
安装 + 使用
1 | npm install --save-dev babel-cli babel-preset-env |
watch
watch 命令行工具可以监控文件的改动1
2npm i -g watch-cli
watch -p 'path1' -c 'cp path1 path2' // 只要 path1 中的文件改动就会将 path1 中的文件复制到 path2 中
watch 也可以用于 img1
watch -p 'src/img/**/*' -c 'cp -r src/img dist/img'
前端目录规范
src ==> source 目录 ==> 未经翻译的代码
dist ==> distribution 目录 ==> 待发布的代码
node_modules ==> 第三方包
vendors ==> 第三方代码(jQuery)
Webpack
通过之前的介绍,我们使用
scss ==> node-sass ==> css
ES6 JS ==> babel ==> ES5(IE 使用)
HTML + img ==> watch ==> 复制
我们通过这么多的命令才能实现我们的自动化,那么为什么不使用一种工具,具有以上三者的作用呢,所以 Webpack 应运而生
Webpack 核心
入口(entry)
entry 指示 webpack 使用哪个模块来作为构建其内部依赖图的开始,进入进口后,webpack 会找出有哪些模块和库是入口直接或间接依赖的,每个依赖项随即被处理,最后输出到 bundles 的文件中
通过在 webpack 配置中配置 entry
属性来指定起点1
2
3
4webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js'
}
出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件1
2
3
4
5
6
7
8webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve( __dirname, 'dist' )
filename: 'my-first-webpack-bundle.js'
}
}
loader
loader 让 webpack 能够去处理非 JavaScript 文件(webpack 自身只能理解 JavaScript)。webpack loader 将所有类型的文件,转换为应用程序的依赖图可以直接引用的模块。多数 loader 可以通过选项(options
)自定义
loader 实现的目标
- 识别出应该被对应的 loader 进行转换的那些文件(使用
text
属性) - 转换这些文件,使其能被添加到依赖图中(使用
use
属性)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve( __dirname, 'dist' )
filename: 'my-first-webpack-bundle.js'
},
module: {
rules: [
{
// 遇到匹配的文件,使用 loader 进行转换之后再进行打包
text: /\.txt$/, // 匹配的文件
use: 'raw-loader' // 使用的 loader
use: {
loader: 'babel-loader',
options: {
presets: [ '@babel/present-env' ]
}
}
}
]
}
}
插件(plugins)
loader 被用于转换某些类型的模块,而插件则用于执行范围更广的任务。插件的范围包括:从打包优化 + 压缩,一直到重新定义环境中的变量
想使用一个插件,需要 require()
插件,然后把它添加到 plugins
数组中,多数插件可以通过选项 options
自定义1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
webpack 使用
注意:npm i 找不到的module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27mkdir webpack-demo
cd webpack-demo
npm init // 初始化
一路回车
ls ==> package.json
npm install --save-dev webpack // package.json 中多了依赖 webpack
touch webpack.config.js // 创建配置文件并编辑
vi webpack.config.js
****************
const path = require('path');
module.exports = {
entry: './src/js/',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist/js/')
}
};
*****************
mkdir src src/css src/js
touch src/css/main.scss src/js/index.js src/js/main.js src/index.html
****************
index.html 中引入 css,不引 scss
<link rel="stylesheet" href="./css/main.css">
***************
npx webpack // 将 src 中的 JS 文件转换 + 复制到 dist/js/
使用 babel-loder
1 | index.js + main.js |
模块化
1 | touch src/js/app.js |
使用 scss-loader
1 | npm install sass-loader node-sass webpack --save-dev |
使用 postcss-loader
postcss-loader 能够使得 CSS 自动添加前缀,从而使我们的代码更加强健1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43npm i -D postcss-loader
touch postcss.config.js
vi postcss.config.js
*****************************
module.exports = {
//parser: 'sugarss',
plugins: {
'postcss-import': {},
// 'postcss-cssnext': {},
// 'cssnano': {}
}
}
*******************************
vi webpack.config.js
************************
......
{
test: /\.scss$/,
use: [
{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader", // translates CSS into CommonJS
+ options: { importLoaders: 1 }
+ }, {
+ loader: 'postcss-loader',
+ options: { // 如果没有 options 则不会添加后缀,先尝试不添加 options,如果 postcss-loader 不工作,再添加 options
+ plugins: () => [
+ require('autoprefixer')
+ ]
+ }
},{
loader: "sass-loader" // compiles Sass to CSS
}
]
}
......
***********************
npx webpack
webpack 总结
- webpack 将前端思想完全转变,将 CSS 写入 JS 中,使用 JS 生成