-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Serve styles and assets using .angular-cli webpack configuration #2735
Changes from 8 commits
3ad322f
b91744c
91e5353
2a5f4bc
fb7bd69
6155a0d
1ccbe21
037c08b
a21777f
3ad33cc
dc8c138
d20da16
44ec036
d973880
8039b0a
2539764
25d2fdb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
|
||
const logger = console; | ||
|
||
export function isAngularCliInstalled() { | ||
try { | ||
require.resolve('@angular/cli'); | ||
return true; | ||
} catch (e) { | ||
return false; | ||
} | ||
} | ||
|
||
export function getAngularCliWebpackConfigOptions(dirToSearch, appIndex = 0) { | ||
const fname = path.join(dirToSearch, '.angular-cli.json'); | ||
if (!fs.existsSync(fname)) { | ||
return null; | ||
} | ||
const cliConfig = JSON.parse(fs.readFileSync(fname, 'utf8')); | ||
if (!cliConfig.apps || !cliConfig.apps.length) { | ||
throw new Error('.angular-cli.json must have apps entry.'); | ||
} | ||
const appConfig = cliConfig.apps[appIndex]; | ||
|
||
const cliWebpackConfigOptions = { | ||
projectRoot: dirToSearch, | ||
appConfig, | ||
buildOptions: { | ||
outputPath: 'outputPath', // It's dummy value to avoid to Angular CLI's error | ||
}, | ||
supportES2015: false, | ||
}; | ||
|
||
return cliWebpackConfigOptions; | ||
} | ||
|
||
export function applyAngularCliWebpackConfig(baseConfig, cliWebpackConfigOptions) { | ||
if (!cliWebpackConfigOptions) return baseConfig; | ||
|
||
if (!isAngularCliInstalled()) { | ||
logger.info('=> Using base config because @angular/cli is not installed.'); | ||
return baseConfig; | ||
} | ||
|
||
// eslint-disable-next-line global-require, import/no-extraneous-dependencies | ||
const ngcliConfigFactory = require('@angular/cli/models/webpack-configs'); | ||
|
||
let cliCommonConfig; | ||
let cliStyleConfig; | ||
try { | ||
cliCommonConfig = ngcliConfigFactory.getCommonConfig(cliWebpackConfigOptions); | ||
cliStyleConfig = ngcliConfigFactory.getStylesConfig(cliWebpackConfigOptions); | ||
} catch (e) { | ||
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. I'd like to see this changed a bit. I'd like to extract a function that detects the installment of If it's not installed, we just merge the base, we might log that. |
||
logger.warn('=> Failed to get angular-cli webpack config.'); | ||
return baseConfig; | ||
} | ||
logger.info('=> Get angular-cli webpack config.'); | ||
|
||
// Don't use storybooks .css/.scss rules because we have to use rules created by @angualr/cli | ||
// because @angular/cli created rules have include/exclude for global style files. | ||
const styleRules = baseConfig.module.rules.filter( | ||
rule => | ||
!rule.test || (rule.test.toString() !== '/\\.css$/' && rule.test.toString() !== '/\\.scss$/') | ||
); | ||
|
||
// cliStyleConfig.entry adds global style files to the webpack context | ||
const entry = { | ||
...baseConfig.entry, | ||
...cliStyleConfig.entry, | ||
}; | ||
|
||
const mod = { | ||
...baseConfig.module, | ||
rules: [...cliStyleConfig.module.rules, ...styleRules], | ||
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. Do we actually need these 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. Sorry, the variable name I'll change the variable's name. |
||
}; | ||
|
||
// We use cliCommonConfig plugins to serve static assets files. | ||
const plugins = [...cliStyleConfig.plugins, ...cliCommonConfig.plugins, ...baseConfig.plugins]; | ||
|
||
return { | ||
...baseConfig, | ||
entry, | ||
module: mod, | ||
plugins, | ||
}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,10 @@ import fs from 'fs'; | |
import path from 'path'; | ||
import loadBabelConfig from './babel_config'; | ||
import loadTsConfig from './ts_config'; | ||
import { | ||
getAngularCliWebpackConfigOptions, | ||
applyAngularCliWebpackConfig, | ||
} from './angular-cli_config'; | ||
|
||
// avoid ESLint errors | ||
const logger = console; | ||
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. This should use 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. @Quramy, I think this is the last comment to take care of |
||
|
@@ -39,6 +43,12 @@ export default function(configType, baseConfig, configDir) { | |
config.entry.manager.unshift(storybookDefaultAddonsPath); | ||
} | ||
|
||
// Check whether project has Angular CLI configuration file | ||
const cliWebpackConfigOptions = getAngularCliWebpackConfigOptions(process.cwd()); | ||
if (cliWebpackConfigOptions) { | ||
logger.info('=> Loading angular-cli config.'); | ||
} | ||
|
||
// Check whether user has a custom webpack config file and | ||
// return the (extended) base configuration if it's not available. | ||
const customConfigPath = path.resolve(configDir, 'webpack.config.js'); | ||
|
@@ -48,15 +58,16 @@ export default function(configType, baseConfig, configDir) { | |
const configPath = path.resolve(__dirname, './config/defaults/webpack.config.js'); | ||
const customConfig = require(configPath); | ||
|
||
return customConfig(config); | ||
return applyAngularCliWebpackConfig(customConfig(config), cliWebpackConfigOptions); | ||
} | ||
const customConfig = require(customConfigPath); | ||
|
||
if (typeof customConfig === 'function') { | ||
logger.info('=> Loading custom webpack config (full-control mode).'); | ||
return customConfig(config, configType); | ||
return customConfig(applyAngularCliWebpackConfig(config, cliWebpackConfigOptions), configType); | ||
} | ||
logger.info('=> Loading custom webpack config (extending mode).'); | ||
|
||
return { | ||
...customConfig, | ||
// We'll always load our configurations after the custom config. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.red-color { | ||
color: red; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<div> | ||
<p class="red-color">Styled with scoped CSS</p> | ||
<p class="blue-color">Styled with scoped SCSS</p> | ||
<p class="green-color">Styled with global CSS</p> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
div { | ||
p.blue-color { | ||
color: blue; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { storiesOf } from '@storybook/angular'; | ||
import { StyledComponent } from './styled.component'; | ||
|
||
storiesOf('Component styles', module).add('Component with styles', () => ({ | ||
component: StyledComponent, | ||
})); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Component } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'storybook-styled-component', | ||
templateUrl: './styled.component.html', | ||
styleUrls: ['./styled.component.css', './styled.component.scss'], | ||
}) | ||
export class StyledComponent {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,5 @@ | ||
/* You can add global styles to this file, and also import other style files */ | ||
|
||
.green-color { | ||
color: green; | ||
} |
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.
Why exporting it?