Global of the CSS

For a long time CSS has always been a global presence on the page. In the past, this “feature” has not been a big impact. Pay attention to naming, such as using BEM, can also solve the problem to a certain extent.

But as web componentization needs more and more intense, this feature has become bound of CSS developers a rope to fly, every CSS class names may have an unintended, or covered by various components to cover, when modifying a component, we must be cautious, pay attention to the conflict in a global environment.

More seriously, in the context of componentization, JS + template + CSS can only be called a complete component. If each component references a SINGLE CSS file, you can only avoid possible conflicts between different components by restricting class names. At the same time, because of the global nature of CSS, the styles of components can affect each other, which completely breaks the principle of low coupling and high cohesion of components.

Of course, CSS isn’t really a programming language, it’s just a DSL, and we couldn’t ask for that much of it, but reluctant programmers have come up with all sorts of ways to make CSS more like a programming language, from SASS and Less to the current launch of CSS in JS, all aimed at solving this problem.

CSS Modules take a different approach, which adds the concept of local/global scope to CSS writing.

CSS Modules

The CSS Module rules are very simple: anything that you don’t specify as a global scope will be handled locally.

Take SASS as an example. Say you write a paragraph:

.title {
    height: 80px;
    line-height: 80px;
    font-size: 24px;
    color: #0a95bf;
}Copy the code

The pattern that comes out is:

.title_1hf8_ {
    height: 80px;
    line-height: 80px;
    font-size: 24px;
    color: #0a95bf
}Copy the code

Title becomes title_1HF8_ as you might guess, the CSS Module implements local scope by encoding classes according to certain rules.

The reference in the component looks like this:

import * as Style from './index.scss';Copy the code

This can then be used in templates:

<div v-bind:class="Sytles.title">MD Converter</div>Copy the code

The resulting HTML is:

<div class="title_1hf8_">MD Converter</div>Copy the code

TypeScript and Vue are used here, and the same is true elsewhere.

With “local scope” in place, here’s the global scope:

:global { .output { background: #fff; height: 100%; min-height: 100%; padding: 1em; word-break: break-all; }}Copy the code

Just wrap the things you want as global scopes in :global{}.

Work with SASS and TypeScript

Webpack’s CSS-Loader can be used with CSS modules, but TypeScript is a bit different.

Let’s start with the complete Webpack configuration file:

var path = require('path');
var webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    // Page entry file configuration
    entry: {
        "index.entry": __dirname + '/src/js/index.entry.js',},// Import file output configuration
    output: {
        filename: '[name].js'.chunkFilename: "[name].chunk.js",},externals: {
        "vue": "Vue",},plugins: [
        new webpack.optimize.UglifyJsPlugin({
          compress: {warnings: false},
          output: {comments: false},
          sourceMap: true})].module: {
        rules: [{test: /\.html$/.loader: 'text-loader'
            },
            {
                test: /\.scss$/.use: ExtractTextPlugin.extract({
                    fallback: {
                        loader: 'style-loader'.options: {
                            insertAt: 'top'}},use: [{loader: 'typings-for-css-modules-loader'.options: {
                                modules: true.namedExport: true.camelCase: true.minimize: true.localIdentName: "[local]_[hash:base64:5]"}}, {loader: 'sass-loader'.options: {
                                outputStyle: 'expanded'.sourceMap: true}}]})},],},plugins: [
        new ExtractTextPlugin({
            filename: (getPath) = > {
                return getPath('.. /css/[name].css').replace('css/js'.'css');
            },
            allChunks: true})]};Copy the code

Three loaders are mainly used here, namely ass-loader, typings-for-CSS-modules-loader and style-loader.

If TypeScript does not replace typings-for-CSS-modules-loader with CSS-loader, change the configuration slightly.

Enabling CSS Modules is easy, just modules: true, and then the localIdentName option: “[local]_[hash:base64:5]” is used to specify the rule that generates class names. Title_1hf8_ is based on this rule. You can also make it more complicated, such as [path][name]__[local]–[hash:base64:5].

The functions of the three loaders are explained briefly:

  1. Sass-loader, of course, compiles sASS files into CSS files;
  2. Typings-for-css-modules-loader is a layer package on CSS-Loader, and its options are fully compatible with CSS-Loader. In addition, it generates a corresponding xxx.scs.d. ts explanation file for each SASS file, which is parsed correctly in TypeScript and has very friendly code prompts in the editor.
  3. Style-loader simply uses styles<style>The tag hits the page.

The whole process is to read an SCSS file, throw it to sass-Loader and process it into CSS, The typings-for-CSs-modules-loader file is then generated to xxx.scs.d. ts and the CSS is processed to make JavaScript usable. Webpack can only handle JavaScript, so it needs to be converted), and finally it will be processed by style-loader, and the page will be typed on the page when it loads.

The essence of a loader is anything to JavaScript, because Webpack only handles JavaScript. With this in mind, we have a clear idea of why we use this loader and that loader.

When writing a Vue component in TypeScript, you can define the component by requiring an HTML template:

@Component({
    template: require('./index.html'})),Copy the code

The webpack configuration contains the following:

            {
                test: /\.html$/,
                loader: 'text-loader'
            },Copy the code

Use a text-loader to process HTML files, require HTML into a text, use Webpack, templates and code elegant separation.

other

In addition, CSS Modules have features such as defining variables, inheriting classes, and importing other Modules, but most of these SASS also have features.

Finally, as a simple example, TypeScript + Vue’s Markdown simple editor.

Demo code address: github.com/bob-chen/md

twitter

Record some thoughts and thoughts, write science and technology and humanities, write life conditions, write reading experience, mainly bullshit and feeling. Welcome to pay attention and exchange.

Wechat official number: poem and distance of programmer

Public ID: Monkeycoder-Life

reference

www.ruanyifeng.com/blog/2016/0…

Github.com/camsong/blo…