正文
这里不止一种方法来让CSS模块与JavaScript模板、CSS文件或者构建步骤运行起来。这篇文章作为CSS模块系列文章的一部分,我们学习一种方法。本文的目的就是开始一个CSS模块项目并且运行起来。
系列文章
Part 1: 什么是CSS模块以及你为什么需要它?
Part 2: 如何开始CSS模块 (你在这里!)_
Part 3: React + CSS Modules = ?
在这个项目中,要求CSS决不能依赖客户端JavaScript运行,所以构建步骤需要在部署之前将所有东西处理成可运行的HTML和CSS。我们将使用
Webpack
,一款构建系统和模块打包工具。在下一篇文章中我们将集中使代码处于一个渲染静态HTML的浏览器的真实的项目中。
开始吧!
安装Webpack
安装NPM和node
以后,我们需要在某处创建一个文件夹并且运行以下代码:
npm init --y
这将创建一个充满一系列默认值的
package.json
文件。这是我们的依赖清单——当别人
npm install
这个项目时需要下载和安装的依赖的指示。
Webpack
将处理我们的构建过程。它将在我们写代码的过程中监测我们的CSS,JavaScript,HTML以及执行。但是什么是Webpack?
Maxime Fabre认为Webpack是一款构建系统和模块打包工具
:
嗯,这两者都和我的意思,这不是我的意思,我的意思是,它结合了这两种。Webpack并没有建立自己的资源,然后分别打包你的模块,它认为你的资源是模块本身...它们能够被引入、修改、操作并且最终能够打包到你的最终文件。
如果这听起来很奇怪,不要担心。记得曾经Sass、Gulp、npm曾经都那么陌生和可怕吗?我们稍后将解决它。
让我们确信Webpack通过一个JavaScript文件定义代码的依赖关系,因此我们能够引入代码块来实现正确的“打包”。首先我们需要在全局安装Webpack,这让我们能够在我们的终端运行
webpack
命令:
npm install webpack -g
一旦这个完成,我们需要在我们项目的本地安装Webpack,像这样:
npm i -D webpack
现在我们需要在
/src
文件夹下新建一个
index.js
文件。通常我喜欢创建一个文件夹来存放静态资源(比如图片、字体、CSS文件和标记)。我写的代码一般都在
/src
文件夹下,同时那些在过程中通过机器或者编译的代码存放在
/build
文件夹下。我认为删除
/build
文件夹是完全没有问题也不会遭受任何痛苦的,因为我们完全可以运行命令行代码,它将处理
/src
文件夹内的东西并且再一次将它完全的重建为
/build
文件夹。在这种情况下,我们希望Webpack查看
/src
下的所有东西,执行某一过程,随后将结果的代码放入
/build
。
在
/src
文件夹内我们新建一个空的
alert.js
文件(我们随后将回看它。)我们将需要在项目的根目录,
/src
文件夹外创建一个
webpack.config.js
文件,因此我们的项目结构是这样的:
package.json
webpack.config.js
/node_modules
/src
index.js
alert.js
在
webpack.config.js
文件(webpack配置文件)内,我们需要加入以下代码:
module.exports = {
entry: './src',
output: {
path: 'build',
filename: 'bundle.js',
},
};
每当我们运行
webpack
命令时,Webpack将查看
/src
中的所有资源建立一个依赖关系树。
返回我们的
src/index.js
文件中添加以下代码:
require("./alert.js");
并且在
alert.js
文件中写入:
alert("LOUD NOISES");
现在在我们的根目录再创建一个
index.html
文件,并且在
<body>
关闭标签前加入script标签引入我们打包的文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document name</title>
</head>
<body>
<h1>CSS Modules demo</h1>
<script src="build/bundle.js"></script>
</body>
</html>
bundle.js
就是Webpack将要生成的文件。要生成它我们需要运行
webpack
命令。为了让我们更方便的使用它,我们需要在
package.json
文件中更新scripts。我们需要在
package.json
文件中找到它:
"scripts": {
"test": "echo 'Error: no test specified' && exit 1"
},
这是
npm
默认给我们的,但是我们可以使用以下的代码替换它,并且让我们的命令行脚本为我们运行Webpack以及打开一个浏览器窗口:
"scripts": {
"start": "webpack && open index.html"
},
所以无论何时当我们运行
npm start
时我们将自动运行
webpack
命令以及在浏览器打开我们的index文件。让我们现在来运行一下,看看发生了什么。
✌️,运行成功了!这证明了我们的
index.js
文件从
alert.js
文件中引入了它,并且Webpack正确的打包了一切。如果我们现在删除
alert.js
文件,我们将在再一次运行
npm start
时发现一个错误:
这个错误将在Webpack未能找到引入的模块时出现。但现在,我们已经证实,我们运行的都可以完成。现在我们可以在我们的
index.js
中取消
require
,开始学习Webpack的下一步。
添加我们的第一个加载器(Loader)
Webpack中的加载器非常重要。MaxIME Fabre在这方面有他的
看法
:
加载器基本上是一种“当你遇到这种类型的文件时,使用这个loader加载它”的一种小型插件。
在Maxime的教程中他添加了Babel Loader,这真是一个很好的开始,因为
Babel
允许我们使用ES2015以及JavaScript语言的最新改进。所以,代替我们之前使用的Common.js的
require
函数,我们现在可以使用
import
。通过Babel,我们也可以使用classes(类),arrow functions(箭头函数)以及
一系列其他很酷的特性
:
Babel这类工具允许我们在现在就书写新的ES2015代码,并且执行一个称为转译(和预处理比较像)的任务来将代码转换为能得到浏览器很好的支持的早一些的JavaScript版本。这与Sass很像;最初使用Sass语法写代码,随后使用预处理器编译为标准的CSS。
下面的代码将安装Webpack babel loader 以及我们运行Babel需要的依赖:
npm i -D babel-loader babel-core babel-preset-es2015
在根目录下的
.babelrc
文件中我们可以配置预设值让其他人知道我们将使用哪种JavaScript语法:
{
"presets": ["es2015"]
}
现在我们想要Babel运行在那些我们写的
.js
文件上,那些我们随后安装的依赖有他们自己的语法,我们并不想弄乱它们。这时我们就需要Webpack。我们可以打开
webpack.config.js
文件并且用以下代码替换它:
module.exports = {
entry: './src',
output: {
path: 'build',
filename: 'bundle.js',
},
module: {
loaders: [
{ test: /\.js/, loader: 'babel', include: __dirname + '/src', }
],
}
};
loaders
数组中的
test
键值对告诉Webpack在什么类型的文件上操作。同时
include
明确告诉webpack我们想要在项目的什么地方进行操作。
让我们测试一下Babel和Webpack一起工作。在一个新的文件(
src/robot.js
)中,我们写入以下代码:
const greetings = (text, person) => {
return `${text}, ${person}. I read you but I’m sorry, I’m afraid I can’t do that.`;
}
export default greetings;
这个JavaScript文件用了一系列ES2015的新特性,比如
export
,
const
和
let
,箭头函数,模板字符串。
现在我们可以
import
那个模块到我们的
src/index.js
文件,像这样:
import greetings from './robot.js'
document.write(greetings("Affirmative", "Dave"));
最后,我们所需要做的就是再次运行
npm start
,我们的浏览器应该弹出一段文字:“Affirmative, Dave. I read you but I’m sorry, I’m afraid I can’t do that.”。这就证实了Babel正如它应该的工作了。
加油!尽管我们只差一步了,但目前它还不是一个CSS模块。但是在我们继续之前,让我们删除
src/robot.js
以及
src/index.js
中的代码。
加载样式
现在我们几乎让我们的模板工作了,我们将需要再添加两个loaders,
css-loader
和
style-loader
,我们将安装:
npm i -D css-loader style-loader
css-loader查看CSS文件的所有依赖,style-loader将这些样式直接嵌入到标记中。让我们在
src/app.css
中写些代码来测试:
.element {
background-color: blue;
color: white; font-size: 20px;
padding: 20px;
}
随后我们在
src/index.js
中
import
这个样式表。
import styles from './app.css'
let element = `
<div class="element">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur laudantium recusandae itaque libero velit minus ex reiciendis veniam. Eligendi modi sint delectus beatae nemo provident ratione maiores, voluptatibus a tempore!</p> </div> `
document.write(element);
坚持住!我们刚才将一个样式表作为JavaScript文件的依赖了吗?当然咯!但是在它正确运行以及我们知道它为什么有用之前,我们首先需要再次配置
webpack.config.js
:
module.exports = {
entry: './src',
output: {
path: 'build',
filename: 'bundle.js',
},
module: {
loaders: [
{ test: /\.js/, loader: 'babel', include: __dirname + '/src', },
{ test: /\.css/, loaders: ['style', 'css'], include: __dirname + '/src' }
],
}
};
运行
npm start
将看到:
这样,如果我们"Inspect Element"我们的文档,我们将发现style-loader将那个文件放入
<style>
标签中嵌入到了文档的
<head>
标签中: