-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve heft-webpack-basic-tutorial to illustrate .scss support #3
base: main
Are you sure you want to change the base?
Changes from 6 commits
6eebb22
8e8feb6
979323e
29b68b1
7ed035a
2823381
ddf34ea
4b958b1
ab7a552
6a26478
126809d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. | ||
{ | ||
"pnpmShrinkwrapHash": "bc4e7aed1c0d15c3e770eb41cddc9b0c6dce54f6" | ||
"pnpmShrinkwrapHash": "67ffd7e6d1eea39ab8245465c4563f09f775a35c" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Documentation for .scss syntax: https://sass-lang.com/documentation/syntax | ||
|
||
// Example of a SASS variable: | ||
$height: 20px; | ||
|
||
.frame { | ||
border-radius: 10px; | ||
width: 35px; | ||
height: $height; | ||
cursor: pointer; | ||
} | ||
|
||
.sliderLeft { | ||
border-radius: 10px; | ||
background-color: #c0c0c0; | ||
width: 20px; | ||
height: $height; | ||
|
||
margin-left: 0px; | ||
margin-right: auto; | ||
} | ||
|
||
.sliderRight { | ||
border-radius: 10px; | ||
background-color: #c0c0c0; | ||
width: 20px; | ||
height: $height; | ||
|
||
margin-left: auto; | ||
margin-right: 0px; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
'use strict'; | ||
|
||
const path = require('path'); | ||
const sass = require('sass'); | ||
const autoprefixer = require('autoprefixer'); | ||
const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||
const { DefinePlugin } = require('webpack'); | ||
|
||
/** | ||
* If the "--production" command-line parameter is specified when invoking Heft, then the | ||
|
@@ -12,45 +15,171 @@ function createWebpackConfig({ production }) { | |
// Documentation: https://webpack.js.org/configuration/mode/ | ||
mode: production ? 'production' : 'development', | ||
resolve: { | ||
// Important: Do NOT add TypeScript extensions here | ||
extensions: ['.js', '.jsx', '.json'] | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.css$/, | ||
use: [require.resolve('style-loader'), require.resolve('css-loader')] | ||
// We recommend the newer .scss file format because its syntax is a proper superset of plain CSS. | ||
// The older .sass syntax is supported only for backwards compatibility. | ||
// The SASS docs are here: https://sass-lang.com/documentation/syntax | ||
test: /\.(scss|sass|css)$/, | ||
exclude: /node_modules/, | ||
use: [ | ||
{ | ||
// Generates JavaScript code that injects CSS styles into the DOM at runtime. | ||
// The default configuration creates <style> elements from JS strings | ||
// https://www.npmjs.com/package/style-loader | ||
loader: 'style-loader' | ||
}, | ||
|
||
{ | ||
// Translates CSS into CommonJS | ||
// https://www.npmjs.com/package/css-loader | ||
loader: 'css-loader', | ||
options: { | ||
// 0 => no loaders (default); | ||
// 1 => postcss-loader; | ||
// 2 => postcss-loader, sass-loader | ||
importLoaders: 2, | ||
|
||
// Enable CSS modules: https://github.com/css-modules/css-modules | ||
modules: { | ||
// The "auto" setting has a confusing design: | ||
// - "false" disables CSS modules, i.e. ":local" and ":global" selectors can't be used at all | ||
// - "true" means magically disable CSS modules if the file extension isn't like ".module.css" | ||
// or ".module.scss" | ||
// - a lambda disables CSS modules only if the lambda returns false; the function parameter is | ||
// the resource path | ||
// - a RegExp disables CSS modules only if the resource path does not match the RegExp | ||
// | ||
// NOTE: Counterintuitively, if you instead set "modules=true" then CSS modules are enabled | ||
// without magic, equivalent to "auto: () => true" instead of "auto: true" | ||
// | ||
// DEFAULT: "true" (i.e. path based magic) | ||
auto: (resourcePath) => { | ||
// Enable CSS modules unless the filename opts out using a file extension like "filename.global.scss" | ||
return !/\.global\.\w+$/i.test(resourcePath); | ||
}, | ||
|
||
// This setting has no effect unless CSS modules is enabled. Possible values: | ||
// - "local": global CSS by default, overridable using the ":local" selector | ||
// - "global": local CSS by default, overridable using the ":global" selector | ||
// - "pure": requires selectors to contain at least one local class or id | ||
// - a lambda that returns the mode string; the function parameter is the resource path | ||
// | ||
// DEFAULT: "local" | ||
mode: 'local', | ||
|
||
// Set this to true if you want to be able to reference the global declarations using import statements | ||
// similar to local CSS modules | ||
// | ||
// DEFAULT: false | ||
// exportGlobals: true, | ||
|
||
// Provide a recognizable class/module names for developers | ||
// | ||
// DEFAULT: "[hash:base64]" | ||
localIdentName: production ? '[hash:base64]' : '[local]__[hash:base64:5]' | ||
}, | ||
|
||
sourceMap: !production | ||
} | ||
}, | ||
|
||
{ | ||
// PostCSS is a general-purpose CSS transformer; however, we prefer to avoid custom CSS syntaxes | ||
// and only use the standard SASS syntax. Thus postcss-loader is used here only to apply the popular | ||
// "autoprefixer" plugin improves browser compatibility by generating vendor prefixes. | ||
// https://www.npmjs.com/package/postcss-loader | ||
loader: 'postcss-loader', | ||
options: { | ||
postcssOptions: { | ||
plugins: [ | ||
// https://www.npmjs.com/package/autoprefixer | ||
autoprefixer | ||
] | ||
}, | ||
|
||
sourceMap: !production | ||
} | ||
}, | ||
|
||
{ | ||
// Compiles SASS syntax into CSS | ||
// https://www.npmjs.com/package/sass-loader | ||
loader: 'sass-loader', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bartvandenende-wm pointed out that this recipe will apply SASS transformations to .css files, which we don't want There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're thinking to change the rig to work like this:
...and if someone wants CSS with modules, they can simply use the There's a small performance penalty for applying SASS to a plain CSS file, but @halfnibble pointed out that the extra syntax validation probably justifies that cost. |
||
options: { | ||
implementation: sass, | ||
sassOptions: { | ||
includePaths: [path.resolve(__dirname, 'node_modules')] | ||
}, | ||
|
||
sourceMap: !production | ||
} | ||
} | ||
] | ||
}, | ||
|
||
{ | ||
test: /\.(jpeg|jpg|png|gif|svg|ico)$/, | ||
// Allows import/require() to be used with an asset file. The file will be copied to the output folder, | ||
// and the import statement will return its URL. | ||
// https://www.npmjs.com/package/file-loader | ||
loader: 'file-loader' | ||
}, | ||
|
||
{ | ||
test: /\.js$/, | ||
enforce: 'pre', | ||
use: ['source-map-loader'] | ||
use: [ | ||
// The source-map-loader extracts existing source maps from all JavaScript entries. This includes both | ||
// inline source maps as well as those linked via URL. All source map data is passed to Webpack for | ||
// processing as per a chosen source map style specified by the devtool option in webpack.config.js. | ||
// https://www.npmjs.com/package/source-map-loader | ||
'source-map-loader' | ||
] | ||
} | ||
] | ||
}, | ||
|
||
entry: { | ||
app: path.join(__dirname, 'lib', 'index.js'), | ||
|
||
// Put these libraries in a separate vendor bundle | ||
vendor: ['react', 'react-dom'] | ||
}, | ||
|
||
output: { | ||
path: path.join(__dirname, 'dist'), | ||
filename: '[name]_[contenthash].js' | ||
}, | ||
|
||
performance: { | ||
// This specifies the bundle size limit that will trigger Webpack's warning saying: | ||
// "The following entrypoint(s) combined asset size exceeds the recommended limit." | ||
maxEntrypointSize: 250000, | ||
maxAssetSize: 250000 | ||
}, | ||
|
||
devServer: { | ||
port: 9000 | ||
port: 9000, | ||
|
||
// The http://localhost namespace should be relative to the "dist" folder | ||
contentBase: path.join(__dirname, 'dist') | ||
}, | ||
|
||
devtool: production ? undefined : 'source-map', | ||
plugins: [ | ||
// See here for documentation: https://github.com/jantimon/html-webpack-plugin | ||
new HtmlWebpackPlugin({ | ||
template: 'assets/index.html' | ||
}), | ||
|
||
// See here for documentation: https://webpack.js.org/plugins/define-plugin/ | ||
new DefinePlugin({ | ||
DEBUG: !production | ||
}) | ||
] | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe @iclanton will remember for certain, but I vaguely remember there being something counterintuitive about the "rootDirs" field that required us to keep both "rootDir" and "rootDirs". I think "rootDir" is used for calculating the root path and if you don't have a TS file in your "src" folder, then you might lose your folder structure without it being also specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@halfnibble good catch!
You are right, despite the name,
rootDir
androotDirs
are very different settings:rootDir
explicitly specifies the folder that will be used as the basis forlib
output; otherwise it will be inferred from the common parent of thefiles
,include
, etcrootDirs
specifies directories with additional typings that will be overlayed on the mainsrc
directory tree, under the assumption that those.js
files will all get copied into the same output folder.Specifying
rootDirs
does not influence therootDir
.As an experiment, with
"rootDir": "src"
deleted in this branch, if I move all my files to besrc/x/*.ts
they wrongly get compiled tolib/*.ts
instead oflib/x/*.ts
.The naming of these settings is very misleading.